在yacc

时间:2018-04-03 10:12:57

标签: bison yacc bnf

我必须为小型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

0 个答案:

没有答案