📄 lab3.y
字号:
%{
#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 + -