JavaCC - 如何在此声明中使订单无关紧要?

时间:2014-10-16 22:07:43

标签: compiler-construction javacc

我基本上有以下声明,并且希望它无论顺序是什么,都要对它内部的东西进行处理。例如,就像当前的代码一样,它会接受" ABS(5)+ 3"但不是" 3 + ABS(5)"。有谁知道我怎么能以任何顺序使它工作?

我认为将所有内容都设为OR,然后用*来包围它会起作用,但这看起来并没有太大的区别。

( ( s1=ABS() { s=s+s1; } )
| ( "+" { op="+"; s=s+op; }
  | "-" { op="-"; s=s+op; }
  | "*" { op="*"; s=s+op; }
  | "/" { op="/"; s=s+op; } ) 
| ( s1=EXPR() { s=s+s1; } ) )*

2 个答案:

答案 0 :(得分:0)

基本上,你做错了。表达式语法应该与任何其他语言一样,expression, term, factor,primary.函数调用ABS()应出现在primary的制作中,而不是其他地方,以及文字,'(' expression ')'等等。

答案 1 :(得分:0)

我认为你几乎走在正确的轨道上。你想要ABS可以是一种EXPR,那么复合表达式的规则可以是

s = EXPR()
(
    (
      "+" { op="+"; s=s+op; } 
    | "-" { op="-"; s=s+op; } 
    | "*" { op="*"; s=s+op; }
    | "/" { op="/"; s=s+op; }
    )
    s1=EXPR() { s=s+s1; }
)*

EXPR的主体看起来像

( s = ABS() | s = NUMBER() )
{return s;}

正如EJP在答案中指出的那样,这并不涉及运营商的优先权,但是目前尚不清楚这是一个直接的目标。此外,您所谓的Expr通常称为Primary。看到 Parsing Expressions by Recursive Descent了解有关优先级和关联性的更多信息。