📄 cm_parse.y
字号:
{
$$ = $1;
}
| return_stmt
{
$$ = $1;
}
;
expression_stmt : expression SEMICOLON
{
$$ = $1;
}
| SEMICOLON
{
$$ = 0;
}
;
selection_stmt : IF LPAREN expression RPAREN statement ELSE statement
{
$$ = newStmtNode(IfK);
$$->child[0] = $3;
$$->child[1] = $5;
$$->child[2] = $7;
}
| IF LPAREN expression RPAREN statement
{
$$ = newStmtNode(IfK);
$$->child[0] = $3;
$$->child[1] = $5;
}
;
while_stmt : WHILE LPAREN expression RPAREN statement
{
$$ = newStmtNode(WhileK);
$$->child[0] = $3;
$$->child[1] = $5;
}
;
for_stmt : FOR LPAREN for_expression SEMICOLON for_expression SEMICOLON for_expression RPAREN statement
{
$$ = newStmtNode(ForK);
$$->child[0] = $3;
$$->child[1] = $5;
$$->child[2] = $7;
$$->child[3] = $9;
}
;
return_stmt : RETURN SEMICOLON
{
$$ = newStmtNode(ReturnK);
}
| RETURN expression SEMICOLON
{
$$ = newStmtNode(ReturnK);
$$->child[0] = $2;
}
;
expression : var ASSIGN expression
{
$$ = newExpNode(OpK);
$$->attr.op = ASSIGN;
$$->child[0] = $1;
$$->child[1] = $3;
}
| or_expression
{
$$ = $1;
}
;
for_expression : var ASSIGN expression
{
$$ = newExpNode(OpK);
$$->attr.op = ASSIGN;
$$->child[0] = $1;
$$->child[1] = $3;
}
| or_expression
{
$$ = $1;
}
| empty
{
$$ = 0;
}
;
empty :;
var : ID
{
$$ = newExpNode(IdK);
$$->lineno = lineno;
$$->attr.name = copyString(tokenString);
}
| ID { $$ = newExpNode(ArrayK); $$->attr.name = copyString(tokenString); } LBRACKET expression RBRACKET
{
$$ = newExpNode(ArrayK);
$$->attr.name = $2->attr.name;
delete($2);
$$->child[0] = $4; /*?*/
}
;
or_expression : or_expression OR and_expression
{
$$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = OR;
}
| and_expression
{ $$ = $1; }
;
and_expression : and_expression AND additive_expression
{
$$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = AND;
}
| additive_expression
{ $$ = $1; }
;
additive_expression : additive_expression EQ rel_expression
{
$$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = EQ;
}
| additive_expression LT rel_expression
{
$$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = LT;
}
| additive_expression GT rel_expression
{
$$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = GT;
}
| additive_expression LE rel_expression
{
$$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = LE;
}
| additive_expression GE rel_expression
{
$$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = GE;
}
| additive_expression NE rel_expression
{
$$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = NE;
}
| rel_expression
{
$$ = $1;
}
;
rel_expression : rel_expression PLUS term
{
$$ = newExpNode(OpK);
$$->child[0] = $1;
$$->child[1] = $3;
$$->attr.op = PLUS;
}
| rel_expression 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 : LPAREN expression RPAREN
{ $$ = $2; }
| var
{ $$ = $1; }
| call
{ $$ = $1; }
| NUM
{
$$ = newExpNode(ConstK);
$$->attr.vali = atoi(tokenString);
$$->attr.vartype = Integer;
}
| FLOATNUM
{
$$ = newExpNode(ConstK);
$$->attr.valf = atof(tokenString);
$$->attr.vartype = Float;
}
| CONSTCHAR
{
$$ = newExpNode(ConstK);
$$->attr.valch = tokenString[1];
$$->attr.vartype = Char;
}
| NOT factor
{
$$ = newExpNode(NotK);
$$->child[0] = $2;
}
;
call : id LPAREN arg_list RPAREN
{
$$ = newExpNode(CallK);
$$->child[0] = $1;
$$->child[1] = $3;
}
| id LPAREN RPAREN
{
$$ = newExpNode(CallK);
$$->child[0] = $1;
}
;
arg_list : expression COMMA arg_list
{
$$ = $1;
$$->sibling = $3;
}
| expression
{
$$ = $1;
}
;
%%
void yyerror(const char * message)
{
fprintf(listing,"Syntax error at line %d: %s\n",lineno,message);
fprintf(listing,"Current token: ");
printToken(yychar, tokenString);
Error = TRUE;
}
/* yylex calls getToken to make Yacc/Bison output
* compatible with ealier versions of the TINY scanner
*/
static int yylex(void)
{
return getToken();
}
TreeNode * parse(void)
{
yyparse();
return savedTree;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -