⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lab3.y

📁 c—语言的句法分析器。读入一个C--语言程序
💻 Y
📖 第 1 页 / 共 2 页
字号:
%{
#include "lab3.h"

#define YYERROR_VERBOSE 1

tablelen = 0;
level = 0;
right = 1;
typecount = 0;
typecheck = 0;
%}

%union {
    char *id;             /* identifier */
    int  value;           /* value */
    char op[3];           /* operator */
    symbol *sign;         /* symbol */
    expr expn;            /* expression */
}
%token  IF ELSE WHILE RETURN VOID INT CHAR ID NUM
        NE LT LE EQ GT GE CHAR_LITERAL STRING_LITERAL
        CDECL STDCALL ELLIPSIS
%nonassoc  IFX
%nonassoc  ELSE
%start  program
%right  '='
%left   '+' '-'
%left   '*' '/'
%token  <id> ID
%token  <id> NUM
%token  <id> CHAR_LITERAL
%token  <id> STRING_LITERAL
%type   <value> type_specifer
%type   <sign> var
%type   <expn> additive_expression
%type   <expn> call
%type   <expn> expression
%type   <expn> factor
%type   <expn> simple_expression
%type   <expn> term
%type   <expn> unary_expression
%type   <op>   addop
%type   <op>   mulop
%type   <op>   relop
%type   <op>   unaryop

%%

program
    :  {
           if (debug) {
               printf("make symboltable[%d]\n",tablelen);
           }
           globaltable = MakeTable(NULL, 0);
           symboltable[tablelen] = globaltable;
           tablelen++;
           if (0 == (argtemp.temp = (int *)malloc(50 * sizeof(int)))) {
               printf("malloc for argument list buffer error\n");
               exit(1);
           }
           argtemp.size = 50;
           if (0 == (arg_in.temp = (int *)malloc(50 * sizeof(int)))) {
               printf("malloc for argument check buffer error\n");
               exit(1);
           }
           arg_in.size = 50;
       }
       declaration_list
       {
           if (debug) {
               printf("program => declaration_list\n");
           }
       }
    ;
declaration_list
    :  declaration_list declaration
       {/*
           if (debug) {
               printf("declaration_list => declaration_list declaration\n");
           }*/
       }
    |  declaration
       {/*
           if (debug) {
               printf("declaration_list => declaration\n");
           }*/
       }
    ;
declaration
    :  var_declaration
       {
           if (debug) {
               printf("declaration => var_declaration\n");
           }
       }
    |  fun_declaration
       {
           if (debug) {
               printf("declaration => fun_declaration\n");
           }
       }
    ;
var_declaration
    :  type_specifer ID ';'
       {
           struct table *tp = symboltable[tablelen-1];
           symbol *p = InsertSym($2, tp);
           if (0 == p) {
               printf("line %3d error: %s :redefinition\n", lineno, $2);
               right = 0;
           } else {
               p->type = $1;
           }
           if (debug) {
               printf("var_declaration => type_specifer ID ;\n");
           }
       }
    |  type_specifer ID '[' NUM  ']' ';'
       {
           struct table *tp = symboltable[tablelen-1];
           symbol *p = InsertSym($2, tp);
           if (0 == p) {
               printf("line %3d error: %s :redefinition\n", lineno, $2);
               right = 0;
           } else {
               p->type = $1;
           }
           if (debug) {
               printf("var_declaration => type_specifer ID [ NUM ] ;\n");
           }
       }
    |  type_specifer '*' ID ';'
       {
           struct table *tp = symboltable[tablelen-1];
           symbol *p = InsertSym($3, tp);
           if (0 == p) {
               printf("line %3d error: %s :redefinition\n", lineno, $3);
               right = 0;
           } else {
               p->type = $1 + 100;
           }
           if (debug) {
               printf("var_declaration => type_specifer * ID ;\n");
           }
       }
    |  type_specifer '*' ID '[' NUM ']' ';'
       {
           struct table *tp = symboltable[tablelen-1];
           symbol *p = InsertSym($3, tp);
           if (0 == p) {
               printf("line %3d error: %s :redefinition\n", lineno, $3);
               right = 0;
           } else {
               p->type = $1 + 100;
           }
           if (debug) {
               printf("var_declaration => type_specifer * ID [ NUM ] ;\n");
           }
       }
    ;
type_specifer
    :  INT
       {
           $$ = INT;
           if (debug) {
               printf("type_specifer => INT\n");
           }
       }
    |  VOID
       {
           $$ = VOID;
           if (debug) {
               printf("type_specifer => VOID\n");
           }
       }
    |  CHAR
       {
           $$ = CHAR;
           if (debug) {
               printf("type_specifer => CHAR\n");
           }
       }
    ;
fun_declaration
    :  fun_tag compound_stmt
       {
           tablelen--;
           level--;
       /*    if (debug) {
               printf("fun_declaration => fun_tag compound_stmt\n");
           }*/
       }
    |  fun_tag ';'
       {
           tablelen--;
           level--;
       /*    if (debug) {
               printf("fun_declaration => fun_tag ;\n");
           }*/
       }
    ;
fun_tag
    :  type_specifer calling_convention ID '(' params ')'
       {
           char *p = InsertFun($3, $1);
           if (0 == p) {
               printf("line %3d error: %s :function redefinition\n", lineno, $3);
               right = 0;
               free(argtemp.temp);
           }
           level++;
           typecount = 0;
           if (0 == (argtemp.temp = (int *)malloc(50 * sizeof(int)))) {
               printf("malloc for argument list buffer error\n");
               exit(1);
           }
           argtemp.size = 50;
           if (debug) {
               printf("fun_tag => type_specifer calling_convention ID\n");
           }
       }
    |  type_specifer ID '(' params ')'
       {
           char *p = InsertFun($2, $1);
           if (0 == p) {
               printf("line %3d error: %s :function redefinition\n", lineno, $2);
               right = 0;
               free(argtemp.temp);
           }
           level++;
           typecount = 0;
           if (0 == (argtemp.temp = (int *)malloc(50 * sizeof(int)))) {
               printf("malloc for argument list buffer error\n");
               exit(1);
           }
           argtemp.size = 50;
           if (debug) {
               printf("fun_tag => type_specifer ID\n");
           }
       }
    ;
params
    :  param_list
       {/*
           if (debug) {
               printf("params => param_list\n");
           }*/
       }
    |  VOID
       {
           if (typecount + 1 > argtemp.size) {
               argtemp.temp = (int *)realloc(argtemp.temp,(argtemp.size + BUFFINCREMENT) * sizeof(int));
               if (0 == argtemp.temp) {
                   printf("realloc for argument list buffer error\n");
                   exit(1);
               }
               argtemp.size += BUFFINCREMENT;
           }
           argtemp.temp[typecount++] = VOID;
           if (debug) {
               printf("params => VOID\n");
           }
       }
    ;
param_list
    :  param_list ',' param
       {/*
           if (debug) {
               printf("param_list => param_list , param\n");
           }*/
       }
    |  param
       {/*
           if (debug) {
               printf("param_list => param\n");
           }*/
       }
    ;
param
    :  type_specifer ID
       {
           struct table *tp = symboltable[tablelen-1];
           symbol *p;

           level++;
           p = InsertSym($2, tp);
           if (0 == p) {
               printf("line %3d error: %s :redefinition\n", lineno, $2);
               right = 0;
           } else {
               p->type = $1;
           }
           level--;
           if (typecount + 1 > argtemp.size) {
               argtemp.temp = (int *)realloc(argtemp.temp,(argtemp.size + BUFFINCREMENT) * sizeof(int));
               if (0 == argtemp.temp) {
                   printf("realloc for argument list buffer error\n");
                   exit(1);
               }
               argtemp.size += BUFFINCREMENT;
           }
           argtemp.temp[typecount++] = $1;
           if (debug) {
               printf("param => type_specifer ID\n");
           }
       }
    |  type_specifer '*' ID
       {
           struct table *tp = symboltable[tablelen-1];
           symbol *p;

           level++;
           p = InsertSym($3, tp);
           if (0 == p) {
               printf("line %3d error: %s :redefinition\n", lineno, $3);
               right = 0;
           } else {
               p->type = $1 + 100;
           }
           level--;
           if (typecount + 1 > argtemp.size) {
               argtemp.temp = (int *)realloc(argtemp.temp,(argtemp.size + BUFFINCREMENT) * sizeof(int));
               if (0 == argtemp.temp) {
                   printf("realloc for argument list buffer error\n");
                   exit(1);
               }
               argtemp.size += BUFFINCREMENT;
           }
           argtemp.temp[typecount++] = $1 + 100;
           if (debug) {
               printf("param => type_specifer * ID\n");
           }
       }
    |  type_specifer ID '[' ']'
       {
           struct table *tp = symboltable[tablelen-1];
           symbol *p;

           level++;
           p = InsertSym($2, tp);
           if (0 == p) {
               printf("line %3d error: %s :redefinition\n", lineno, $2);
               right = 0;
           } else {
               p->type = $1;
           }
           level--;
           if (typecount + 1 > argtemp.size) {
               argtemp.temp = (int *)realloc(argtemp.temp,(argtemp.size + BUFFINCREMENT) * sizeof(int));
               if (0 == argtemp.temp) {
                   printf("realloc for argument list buffer error\n");
                   exit(1);
               }
               argtemp.size += BUFFINCREMENT;
           }
           argtemp.temp[typecount++] = $1;
           if (debug) {
               printf("param => type_specifer ID [ ]\n");
           }
       }
    |  ELLIPSIS
       {
           if (typecount + 1 > argtemp.size) {
               argtemp.temp = (int *)realloc(argtemp.temp,(argtemp.size + BUFFINCREMENT) * sizeof(int));
               if (0 == argtemp.temp) {
                   printf("realloc for argument list buffer error\n");
                   exit(1);
               }
               argtemp.size += BUFFINCREMENT;
           }
           argtemp.temp[typecount++] = ELLIPSIS;
           if (debug) {
               printf("param => ELLIPSIS\n");
           }
       }
    ;
compound_stmt
    :  '{' local_declarations statement_list '}'
       {/*
           if (debug) {
               printf("compound_stmt => { local_declarations statement_list }\n");
           }*/
       }
    ;
local_declarations
    :  local_declarations var_declaration
       {/*
           if (debug) {
               printf("local_declarations =>local_declarations var_declaration\n");
           }*/
       }
    |  /* empty */
    ;
statement_list
    :  statement_list statement
       {/*
           if (debug) {
               printf("statement_list => statement_list statement\n");
           }*/
       }
    |  /* empty */
    ;
statement
    :  expression_stmt
       {/*
           if (debug) {
               printf("statement => expression_stmt\n");
           }*/
       }
    |  compound_stmt
       {/*
           if (debug) {
               printf("statement => compound_stmt\n");
           }*/
       }
    |  if_stmt
       {/*
           if (debug) {
               printf("statement => if_stmt\n");
           }*/
       }
    |  while_stmt
       {/*
           if (debug) {
               printf("statement => while_stmt\n");
           }*/
       }
    |  return_stmt
       {/*
           if (debug) {
               printf("statement => return_stmt\n");
           }*/
       }
    ;
expression_stmt
    :  expression ';'
       {
           if (debug) {
               printf("expression_stmt => expression ;\n");
           }
       }
    |  ';'
       {
           if (debug) {
               printf("expression_stmt => ;\n");
           }
       }
    ;
if_stmt
    :  IF '(' expression ')' statement %prec IFX
       {
           if (debug) {
               printf("if_stmt => IF ( expression ) statement\n");
           }
       }
    |  IF '(' expression ')' statement ELSE statement
       {
           if (debug) {
               printf("if_stmt => IF ( expression ) statement ELSE statement\n");
           }
       }
    ;
while_stmt
    :  WHILE '(' expression ')' statement
       {
           if (debug) {
               printf("while_stmt => WHILE ( expression ) statement\n");
           }
       }
    ;
return_stmt
    :  RETURN ';'
       {
           if (debug) {
               printf("return_stmt => RETURN ;\n");
           }
       }
    |  RETURN expression ';'
       {
           if (debug) {
               printf("return_stmt => RETURN expression ;\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -