编译器如何在解析器进程中区分负数和负数

时间:2014-12-15 06:58:29

标签: compiler-construction yacc lex context-free-grammar

嘿我最近参与了一个编译器开发人员,我遇到了减号( - )和负号(-1)的问题。假设现在我有5--3,5 + -3,如何写一个语法规则,这样在抽象语法树构造过程中,yacc会产生一个正确的抽象语法树? 我的语法是这样的:      expr : constant {} | id {} | exec_expr {}      exec_expr : expr PLUS expr {} | expr MINUS expr {} | expr MUL expr {} | expr DIV expr {}

我现在的想法是拥有一个具有最高顺序(非关联)的UMINUS符号来处理案例。 不知何故,我们的编译器必须将表达式拆分为expr和exec_expr,我已尝试使用该方法但由于某些原因它不起作用。

使用任何其他语言处理此案例的标准解决方案是什么?特别是那些LR(0)自动机。非常感谢!

2 个答案:

答案 0 :(得分:2)

作为实际工程的问题,通常 lexer 不处理带符号的数字。

这意味着解析器可以处理减号,或者作为两个操作数之间的减法(第二个可以是数字),或者作为操作数的负数(操作数可以是数字)。这也使得处理像“a--7”这样的奇怪表达变得容易。所以你需要的只是“MINUS”令牌。

您可以设计词法分析器和解析器,其中词法分析器吞下符号字符。通常它需要来自解析器的反馈才能知道什么是安全的。这对于组织起来不方便,因此也就是实际的工程方法。

答案 1 :(得分:1)

您只需添加两条规则:

expr
: constant {}
| id {}
| exec_expr {}
| '+' expr {}  // added
| '-' expr {}  // added

并定义适当的优先级。我希望以传统的方式完整地写出来:

expr
: term
| term '+' term
| term '-' term
;

term
: factor
| factor '*' factor
| factor '/' factor
| factor '%' factor // if you have the % operator
;

factor
: unary
| unary '^' factor // if you have an exponentiation operator. Note right-associativity
;

unary
: primary
| '+' unary
| '-' unary
;

primary
: id
| constant
| '(' expr ')'
;

E&安培; OE