如何解决此 S/R 冲突



这是我工作的EBNF语法的简化:

%token NEWLINE BLOCK_MARK A
%start file
file: block+ NEWLINE*;
block: BLOCK_MARK line;
line: A+;

和 EOF 都吐出 NEWLINE 作为标记(因此在 EOF 之前不需要单个结尾 NEWLINE)。它适用于这样的流:

BLOCK_MARK A A BLOCK_MARK A NEWLINE[actually EOF]

现在我想在block中有几个line,至少一个是强制性的,其余的用NEWLINE分开。 例如:

BLOCK_MARK A A NEWLINE A A BLOCK_MARK A A A EOF

我尝试这样做:

file: block+ NEWLINE*;
block: BLOCK_MARK line moreline*;
line: A+;
moreline: NEWLINE line;

但吉森抱怨说,当展望是NEWLINE时,S/R冲突。我想状态机在决定NEWLINE是新块line的一部分还是file中的最终NEWLINE*(这是必需的,因为文件可以以 NEWLINE/EOF 结尾)感到困惑。

我该如何解决这个问题?

你想要的是使换行符成为前一行的一部分,将除一行以外的任何内容的减少推迟到你看到换行符之后。 所以你最终会得到:

file: block+ ;
block: BLOCK_MARK line_nl+ line_nonl? | BLOCK_MARK line_nonl ;
line_nl: line NEWLINE ;
line_nonl: line ;
line: A+ ;

现在上面唯一的问题是它不允许任何空行(空行将是语法错误)。 但这与您的原始语法相同。

基于克里斯·多德的想法,但在我的第一次尝试中发生了逆转。基本的想法只是在file处移除NEWLINE*,毕竟这已经被line覆盖了。

file: block+;
block: BLOCK_MARK line_nonl line_nl* NEWLINE?;
line_nl: NEWLINE line_nonl;
line_nonl: A+;

我认为这个可以解决所有情况。

相关内容

  • 没有找到相关文章

最新更新