我是编译器构建的新手。我们可以通过Google找到= - * / operations的许多示例,但lex中这些示例中的标记通常只处理一种类型,例如%token<DOUBLE> NUMBER
,然后yacc中的表达式类型将也可以是DOUBLE,例如%type<DOUBLE> expr factor term
。
我为此添加了一个示例语法:
lines
:
| lines expression '\n' { printf(" = %lf\n", $2); }
;
expr
: term { $$ = $1; }
| expr '+' term { $$ = $1 + $3; }
| expr '-' term { $$ = $1 - $3; }
;
term
: factor { $$ = $1; }
| term '*' factor { $$ = $1 * $3; }
| term '/' factor { $$ = $1 / $3; }
;
factor
: NUMBER { $$ = $1; }
| group { $$ = $1; }
;
group
: '(' expression ')' { $$ = $2; }
;
如果我想处理不同的类型,例如FLOAT和INTEGER而不是DOUBLE,我会这样做:
%type<INTEGER> Integer
%type<FLOAT> Float
lines
:
| lines expression '\n' { printf(" = %lf\n", $2); }
;
expr
: term { $$ = $1; }
| expr '+' term { $$ = $1 + $3; }
| expr '-' term { $$ = $1 - $3; }
;
term
: factor { $$ = $1; }
| term '*' factor { $$ = $1 * $3; }
| term '/' factor { $$ = $1 / $3; }
;
factor
: Integer { $$ = $1; }
| Float { $$ = $1;}
| group { $$ = $1; }
;
group
: '(' expression ')' { $$ = $2; }
;
如何定义表达式的类型,如expr,factor,term,constant?
如果我没有为它们分配类型,则会出现错误,表示表达式是无类型的,但是如果我为它们分配类型INTEGER,那么也会出现错误,因为该因子可以减少为INTEGER或FLOAT。
如何处理?
答案 0 :(得分:2)
类型推断(确定表达式的类型)通常不由解析器本身处理,而是稍后在语义分析阶段确定,例如,通过使用getType()函数可以接受任何AST节点并返回其类型。