【问题标题】:Design a caculator with Yacc and Lex that deals with mutiple types用 Yacc 和 Lex 设计一个可以处理多种类型的计算器
【发布时间】:2014-06-05 08:47:41
【问题描述】:

我是编译器构建的新手。我们可以通过 Google 找到很多 =-*/ 操作的示例,但是 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+2,表达式是什么类型?如果输入3.0*2.75,表达式是什么类型?您希望通过语法中的一个 expression 产生式处理这个还是两个(例如 expression_type_intexpression_type_float)?
  • 我想知道是否有任何解决方案可以通过一个表达式来处理它,就像您说的类型 1+2 和在我的语法中键入 3.0*2.75 一样。
  • 好的,所以你想要一些可以同时处理实数和整数,甚至更多的东西,所有这些都在一个单一的数据类型中。您可能想要使用 union,或者更准确地说,使用标记的 union。您必须自己处理所有可能的组合,因为内置算术运算符不适用于联合。为每个运算符编写一个函数,例如MyNumberType add(MyNumberType n1, MyNumberType n2) 并分析其中的每个组合。你会打电话给例如$$=add($1,$3).
  • 所以如果我们想处理不同的类型,我们必须设计一个函数。我们还应该定义表达式的类型吗?感谢您的回复!
  • 表达式的类型是MyNumberType,需要自己定义。您可以通过定义 YYSTYPE 宏(旧的 yacc 方式)或定义 %define api.value.type {MyNumberType}(新的 bison 方式)来实现。您也可以像以前一样使用 %type 声明,但您必须对 所有 作品这样做。

标签: c compiler-construction yacc lex


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多