📄 parser.y
字号:
%{
#define YYPARSER /* distinguishes Yacc output from other code files */
#include "globals.h"
#include "util.h"
#include "scan.h"
#include "parse.h"
#include <stdlib.h>
#define YYSTYPE TreeNode *
static char * savedName; /* for use in assignments */
static int savedLineNo; /* ditto */
static TreeNode * savedTree; /* stores syntax tree for later return */
%}
%token IF ELSE WHILE DO MAIN FOR GOTO CONTINUE BREAK RINT RFLOAT RCHAR
%token ID FLOAT INT CHAR
%token ASSIGN EQ NE LT MT LE ME PLUS MINUS TIMES OVER AND OR NOT LP RP LB RB LS RS SEMI COMMA
%token ERROR
%% /* Grammar for TINY */
program : MAIN LP RP LB stmt_seq RB { savedTree = $5;}
;
stmt_seq : stmt_seq stmt
{ YYSTYPE t = $1;
if (t != NULL)
{ while (t->sibling != NULL)
t = t->sibling;
t->sibling = $2;
$$ = $1; }
else $$ = $2;
}
| {$$ = NULL;}
;
stmt : if_stmt { $$ = $1; }
| while_stmt { $$ = $1; }
| exp_stmt { $$ = $1; }
| decl_stmt { $$ = $1; }
| BREAK SEMI{ $$ = newStmtNode(BreakK); }
| error { $$ = NULL; }
;
if_stmt : IF LP exp RP LB stmt_seq RB
{ $$ = newStmtNode(IfK);
$$->child[0] = $3;
$$->child[1] = $6;
}
| IF LP exp RP LB stmt_seq RB ELSE LB stmt_seq RB
{ $$ = newStmtNode(IfK);
$$->child[0] = $3;
$$->child[1] = $6;
$$->child[2] = $10;
}
;
while_stmt : WHILE LP exp RP LB stmt_seq RB
{ $$ = newStmtNode(WhileK);
$$->child[0] = $3;
$$->child[1] = $6;
}
;
exp_stmt : gen_exp SEMI
{ $$ = newStmtNode(ExK);
$$->child[0] = $1;
}
| SEMI
{ $$ = newStmtNode(ExK);
}
;
decl_stmt : type var_list SEMI
{ YYSTYPE t = $2;
while (t!= NULL){
if($1->kind.type == IntK)
t->type = Integer;
else if($1->kind.type == FloatK)
t->type = Float;
else if($1->kind.type == CharK)
t->type = Char;
else t->type = Void;
t = t->sibling;
}
$$ = newStmtNode(DeclK);
$$->child[0] = $1;
$$->child[1] = $2;
}
;
var_list : var_list COMMA var
{ YYSTYPE t = $1;
$3->attr.isDecl = TRUE;
if (t != NULL)
{ while (t->sibling != NULL)
t = t->sibling;
t->sibling = $3;
$$ = $1; }
else $$ = $3;
}
| var
{ $$ = $1;
$$->attr.isDecl = TRUE;
}
;
/*decl_stmt : type ID
{
savedName=copyString(tokenString);
savedLineNo = lineno;
}
SEMI
{ $$ = newStmtNode(DeclK);
$$->child[0] = $1;
$$->child[1] = newExpNode(IdK);
$$->child[1]->attr.name = savedName;
$$->child[1]->lineno = savedLineNo;
$$->child[1]->attr.isDecl = TRUE;
if($1->kind.type==IntK)
$$->child[1]->type = Integer;
else if($1->kind.type==FloatK)
$$->child[1]->type = Float;
}
| type ID
{ savedName=
copyString(tokenString);
savedLineNo = lineno;
}
LS INT
{ savedLength = atoi(lookAhead);
}
RS SEMI
{ $$ = newStmtNode(DeclK);
$$->child[0] = $1;
$$->child[1] = newExpNode(ArrK);
$$->child[1]->attr.name =savedName;
$$->child[1]->attr.length = savedLength;
$$->child[1]->lineno = savedLineNo;
$$->child[1]->attr.isDecl = TRUE;
if($1->kind.type==IntK)
$$->child[1]->type = Integer;
else if($1->kind.type==FloatK)
$$->child[1]->type = Float;
}
;*/
type : RINT
{ $$ = newTypeNode(IntK);
}
| RFLOAT
{ $$ = newTypeNode(FloatK);
}
| RCHAR
{ $$ = newTypeNode(CharK);
}
;
gen_exp : var ASSIGN gen_exp
{ $$ = newExpNode(AssignK);
$$->child[0] = $1;
$$->child[1] = $3;
}
| exp{ $$ = $1;}
;
exp : exp AND comp_exp
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = AND;
}
|exp OR comp_exp
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = OR;
}
|comp_exp { $$ = $1;}
;
comp_exp : comp_exp LT simple_exp
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = LT;
}
| comp_exp MT simple_exp
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = MT;
}
| comp_exp LE simple_exp
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = LE;
}
| comp_exp ME simple_exp
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = ME;
}
| comp_exp EQ simple_exp
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = EQ;
}
| comp_exp NE simple_exp
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = NE;
}
| simple_exp { $$ = $1; }
;
simple_exp : simple_exp PLUS term
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = PLUS;
}
| simple_exp MINUS term
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = MINUS;
}
| term { $$ = $1; }
;
term : term TIMES factor
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = TIMES;
}
| term OVER factor
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = OVER;
}
| factor { $$ = $1; }
;
factor : LP gen_exp RP
{ $$ = $2; }
| INT
{ $$ = newExpNode(IK);
$$->attr.val.i = atoi(lookAhead);
$$->type = Integer;
}
| FLOAT
{ $$ = newExpNode(FK);
$$->attr.val.f = atof(lookAhead);
$$->type = Float;
}
| CHAR
{
$$ = newExpNode(CK);
$$->attr.val.c = lookAhead[1];
$$->type = Char;
}
| var{ $$ = $1;}
| NOT factor
{ $$ = newExpNode(OpK);
$$->child[0] = $2;
$$->attr.op = NOT;
}
| error { $$ = NULL; }
;
var : | ID { $$ = newExpNode(IdK);
$$->attr.name =
copyString(tokenString);
$$->lineno = lineno;
$$->attr.isDecl = FALSE;
}
| ID { savedName=
copyString(tokenString);
savedLineNo = lineno;
}
LS gen_exp RS
{ $$ = newExpNode(ArrK);
$$->attr.name = savedName;
$$->child[0] = $4;
$$->lineno = savedLineNo;
$$->attr.isDecl = FALSE;
}
;
%%
void yyerror(char * message)
{ fprintf(listing,"Syntax error at line %d: %s\n",lineno,message);
fprintf(listing,"Current token: ");
printToken(yychar,tokenString);
Error = TRUE;
// return 0;
}
/* yylex calls getToken to make Yacc/Bison output
* compatible with ealier versions of the TINY scanner
*/
#ifdef YYPROTOTYPE
int YYCDECL yygettoken(void)
#else
int YYCDECL yygettoken()
#endif
{
return yylex();
}
static int yylex(void)
{ return getToken(); }
TreeNode * parse(void)
{ yyparse();
return savedTree;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -