我必须为小型DSL重写解析器。
我在解析if
语句时遇到了问题。
考虑以下语法。
command
command, command, ... // multiple commands can be written in a line using ','
if expr {
command
...
}
if expr {
command
command, ... // in the if statement as well
...
} command, ... // ugh!, command(s) can be written directly after the if statement
if expr {
command
...
} if ... // and if statement as well
/* ill formed!
if expr
{
...
}
*/
if expr { command } ...
if expr { command, ... } ...
if expr {
...
command } ...
command, ..., if expr { ... } ... // command(s) can be followed by ', if...'
command, ..., if expr {
...
} ...
我知道这个语法缺乏一致性(可能是因为原始的解析器是用纯C编写的)并且很难处理,但是不能再改变了。
我尝试编写yacc规则,但最后是正确的递归。
statlist
: stat
| stat EOL block
| stat ',' block
| ifstat block
ifstat
: 'if' expr '{' statlist '}'
stat
:
| command
如何删除此正确的递归?
或者甚至可能吗? 如果没有,其他解析器生成器(如ANTLR)是否解决了我的问题?
修改
对不起,我的问题一直不清楚。 所以,把它想象成这个。
> s, s, s
command, command, command
> s, f, s, s
command, if statement, statement
> s, f s, s
command, if statement, statement, statement
> s, f f f s, s
command, if statement, if statement, if statement, statement, statement
> s s
error!: commands needs to be separated by a comma
> s f
error!: command and a if statement needs to be separated by a comma
为了完成这项工作,我提出了以下语法
start
: line
| start line
line
: b EOL
b
: s
| s COMMA b
| F b
s
: /* empty */
| S
我认为正确的递归会填满堆栈 is wrong