【发布时间】:2021-11-20 17:02:14
【问题描述】:
我在解决移位/减少冲突时遇到问题。
我正在尝试编写一个while循环语法:
while expression do code() end
问题在于do关键字。
我的一个表达式是一个调用表达式,它也接受一个可选的 do 块用于回调,例如:
function_call() do print("callback") end
这反过来似乎会导致 while 循环的 do 关键字中的 shift/reduce 冲突。
如果我这样做:
while call() do stuff() end
相反,它会尝试将 do 与函数调用相匹配,并弄乱整个解析。
Ruby 有一个非常相似的语法,但它似乎正确地支持 while 循环的 do 关键字而不是表达式。在 Ruby 中,如果需要,您可以将回调放在括号中,这也是我想要解决的理想方式:
while (call() do stuff() end) do more_stuff() end
我该如何克服这个问题?我在运算符优先级定义方面搞砸了很多,但似乎没有任何效果,你将如何解决这个问题? ruby 是如何做到正确的?
这是重现问题的完整语法:
%token IDENT DO END WHILE
%%
program:
%empty
|
stmts
;
stmts:
stmt
|
stmts ';' stmt
|
stmts ';'
;
opt_stmts:
%empty
|
stmts
;
opt_semi:
%empty
|
';'
;
term:
';'
|
DO opt_semi
;
while_loop:
WHILE expr term opt_stmts END
|
WHILE term opt_stmts END
;
stmt:
expr
|
while_loop
;
expr:
IDENT
|
call
|
'(' expr ')'
;
do_block:
DO '|' args '|' opt_stmts END
|
DO opt_stmts END
;
call:
IDENT '(' args ')'
|
IDENT '(' args ')' do_block
|
IDENT do_block
;
args:
%empty
|
expr
|
args ',' expr
|
args ','
;
%%
旁注:我正在使用 Jison,它是 JavaScript 的野牛克隆,因为我正在为 JavaScript 编写编译器,但这不应该成为问题,因为这是一般语法问题和上述最小的 sn-p我写的也跑过原版的 Bison。
【问题讨论】:
-
没有帮助,这主要是关于悬空的其他东西,我似乎无法在这里应用任何东西