📄 parse.y.bak
字号:
/****************************************************/
/* File: tiny.y */
/* The TINY Yacc/Bison specification file */
/* Compiler Construction: Principles and Practice */
/* Kenneth C. Louden */
/****************************************************/
%{
#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 int savedLength;
static int savedIndex;
static TreeNode * savedTree; /* stores syntax tree for later return */
%}
%token IF ELSE WHILE DO MAIN FOR GOTO CONTINUE BREAK RINT RFLOAT
%token ID FLOAT INT
%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 SEMI stmt
{ YYSTYPE t = $1;
if (t != NULL)
{ while (t->sibling != NULL)
t = t->sibling;
t->sibling = $3;
$$ = $1; }
else $$ = $3;
}
| stmt { $$ = $1; }
;
stmt : if_stmt { $$ = $1; }
| while_stmt { $$ = $1; }
| assign_stmt { $$ = $1; }
| decl_stmt { $$ = $1; }
| 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;
}
;
assign_stmt : ID { savedName = copyString(tokenString);
savedLineNo = lineno;
}
ASSIGN exp
{ $$ = newStmtNode(AssignK);
$$->child[0] = newExpNode(IdK);
$$->child[0]->attr.name =savedName;
$$->child[1] = $4;
$$->attr.name = savedName;
$$->lineno = savedLineNo;
}
| ID { savedName = copyString(tokenString);
savedLineNo = lineno; }
LS INT
{ savedIndex = atoi(tokenString);
}
RS ASSIGN exp
{ $$ = newStmtNode(AssignK);
$$->child[0] = newExpNode(ArrK);
$$->child[0]->attr.name = savedName;
$$->child[0]->attr.index = savedIndex;
$$->child[0]->attr.length = 0;
$$->attr.name = savedName;
$$->lineno = savedLineNo;
$$->child[1] = $8;
}
;
decl_stmt : type var_list
{ $$ = newStmtNode(DeclK);
$$->child[0] = $1;
$$->child[1] = $2;
}
;
type : RINT
{ $$ = newTypeNode(IntK);
}
| RFLOAT
{ $$ = newTypeNode(FloatK);
}
;
var_list : var_list COMMA var
{ YYSTYPE t = $1;
if (t != NULL)
{ while (t->sibling != NULL)
t = t->sibling;
t->sibling = $3;
$$ = $1; }
else $$ = $3;
}
| var
{ $$ = $1;
}
;
var : ID
{ $$ = newExpNode(IdK);
$$->attr.name =
copyString(tokenString);}
| ID
{ savedName=
copyString(tokenString);
}
LS INT
{ savedLength = atoi(tokenString);
}
RS
{ $$ = newExpNode(ArrK);
$$->attr.name =savedName;
$$->attr.length = savedLength;
}
;
exp : comp_exp AND comp_exp
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = AND;
}
|comp_exp OR comp_exp
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = OR;
}
|NOT comp_exp
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->attr.op = NOT;
}
;
comp_exp : simple_exp LT simple_exp
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = LT;
}
| simple_exp MT simple_exp
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = MT;
}
| simple_exp LE simple_exp
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = LE;
}
| simple_exp ME simple_exp
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = ME;
}
| simple_exp EQ simple_exp
{ $$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = EQ;
}
| simple_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 exp RP
{ $$ = $2; }
| INT
{ $$ = newExpNode(IK);
$$->attr.val.i = atoi(tokenString);
}
FLOAT
{ $$ = newExpNode(FK);
$$->attr.val.f = atof(tokenString);
}
| ID { $$ = newExpNode(IdK);
$$->attr.name =
copyString(tokenString);
}
| ID { savedName=
copyString(tokenString);
}
LS INT
{ savedIndex= atoi(tokenString);
}
RS { $$ = newExpNode(ArrK);
$$->attr.name = savedName;
$$->attr.index = savedIndex;
}
| error { $$ = NULL; }
;
%%
/*static int 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
*/
int yylex(void)
{ return getToken(); }
TreeNode * parse(void)
{ yyparse();
return savedTree;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -