使用Yacc和Lex设计一个处理多种类型的计算器

时间:2014-06-05 08:47:41

标签: c compiler-construction yacc lex

我是编译器构建的新手。我们可以通过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。

如何处理?

1 个答案:

答案 0 :(得分:2)

类型推断(确定表达式的类型)通常不由解析器本身处理,而是稍后在语义分析阶段确定,例如,通过使用getType()函数可以接受任何AST节点并返回其类型。