我正在尝试编写一个没有回溯的递归下降解析器,用于像这样的 EBNF:
<a> ::= b [c] | d
在哪里
<a> = 非终端
小写字符串 = 标识符
[term-in-brackets] = term-in-brackets 是可选的
a|b 是 a 和 b 之间通常互斥的选择。
现在,我只关心右手边。
按照http://en.wikipedia.org/wiki/Recursive_descent_parser中的示例,我最终得到了以下过程(上述评论中的 GNU bison 语法规则):
/* expression: term optional_or_term */
void expression()
{
term();
if (sym == OR_SYM)
optional_or_term();
}
/* optional_or_term: // empty
| OR_SYM term optional_or_term
*/
void optional_or_term()
{
while (sym == OR_SYM)
{
getsym();
term();
}
}
/* term: factor | factor term */
void term()
{
factor();
if (sym == EOF_SYM || sym == RIGHT_SQUAREB_SYM)
{
;
}
else if (sym == IDENTIFIER_SYM || sym == LEFT_SQUAREB_SYM)
term();
else if (sym == OR_SYM)
optional_or_term();
else
{
error("term: syntax error");
getsym();
}
}
/*
factor: IDENTIFIER_SYM
| LEFT_SQUAREB_SYM expression RIGHT_SQUAREB_SYM
*/
void factor()
{
if (accept(IDENTIFIER_SYM))
{
;
}
else if (accept(LEFT_SQUAREB_SYM))
{
expression();
expect(RIGHT_SQUAREB_SYM);
}
else
{
error("factor: syntax error");
getsym();
}
}
它似乎有效,但我的期望是每个程序都会与相应的规则密切对应。你会注意到 term() 没有。
我的问题是:在编写程序之前,语法是否需要更多的转换?