如果相等构造语法实现



我必须创建识别这一点的语法:

ifequal(exp1, exp2) 
    statement1
smaller
    statement2
larger
    statement3
如果两个表达式相等,则执行语句 1,如果第一个表达式较小,则执行第二个表达式,

如果第三个表达式较大,则执行第三个表达式。我试图制作与此解决方案类似的东西,但没有运气。我不能使用优先级,因此必须正确更改语法。我正在使用杯子工具来生成解析器。

编辑:较小和较大的零件是可选的。

这是古老的悬空如果(如果没有其他)问题。 如果你写一些代码,比如

if (a == b) then
    if (b == c) then
        do_something;
    else
        do_something_else;

解析器在决定"如果"属于哪个"如果"时会遇到问题。一种解决方案是添加一个分隔符,例如"endif"。例:

if (a == b) then
    if (b == c) then
        do_something;
    endif;
    else
        do_something_else;
endif;

不再被缩进所迷惑(我故意做错了),现在很清楚该怎么做。

这就是为什么像下面概述的语法不起作用的原因(它会产生很多冲突):

stmtlist: stmt
    | stmtlist stmt
stmt: ifequal
    | something_else
ifequal: IFEQUAL '(' expr ',' expr ')' stmtlist opt_lt_gt
opt_lt_gt:
    | SMALLER stmtlist
    | LARGER stmtlist
    | SMALLER stmtlist LARGER stmtlist

但是,一旦语句列表以某种方式与 IFEQUAL 语句分离,例如通过使用大括号,问题就会消失。

stmtlist: '{' stmtseq '}'
stmtseq: stmt
     |   stmtseq stmt

另一种可能性是禁止 stmtlist 中的不完整语句。这将或多或少地使您的语法翻倍。它可能看起来像

fullifequal: IFEQUAL '(' expr ',' expr ')' fstmtlist SMALLER fstmtlist LARGER fstmtlist
fstmtlist: fullstmt
    |      fstmtlist fullstmt
fullstmt: fullifequal
    |     some_other
ifequal:  IFEQUAL '(' expr ',' expr ')' fstmtlist opt_lt_gt
opt_lt_gt:
     |     SMALLER fstmtlist
     |     LARGER  fstmtlist
     |     SMALLER fstmtlist LARGER fstmtlist

就个人而言,我更喜欢大括号解决方案,因为它易于阅读,不会限制"ifequal"语句中的语句,并且解析器代码会更短。但我想你需要另一个解决方案。

相关内容

  • 没有找到相关文章

最新更新