[英]Predictive parser for EBNF productions
我正在尝试编写一种递归下降解析器,而不会像这样的EBNF进行回溯:
<a> ::= b [c] | d
哪里
<a> =非终端
小写字符串=标识符
[括号内] =括号内是可选的
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()没有。
我的问题是:在编写程序之前,语法是否需要更多的转换?
我认为您的问题不是缺少用于串联的运算符。 我认为它没有使用Kleene star(和加号)来列出事物。 Kleene星号使您可以在实现语法规则的过程中实际编码一个循环。
我会将您的语法写为:
expression = term (OR_SYM term)*;
term = factor+;
factor = IDENTIFIER_SYM | LEFT_SQUAREB_SYM expression RIGHT_SQUAREB_SYM ;
(这是一个非常经典的语法)。
解析器代码如下所示:
boolean function expression()
{ if term()
{ loop
{ if OR_SYM()
{ if term()
{}
else syntax_error();
}
else return true;
}
else return false;
}
boolean term()
{ if factor()
{ loop
{ if factor()
{}
else return true;
}
}
else return false;
}
boolean factor()
{ if IDENTIFIER(SYM)
return true;
else
{ if LEFT_SQUAREB_SYM()
{ if expression()
{ if RIGHT_SQUAREB_SYM()
return true;
else syntax_error();
}
else syntax_error();
else return false;
}
}
我试图以绝对机械的方式生成此代码,并且您可以做得很好。 在我职业生涯的早期,我做了很多事情。
您每天不会获得150条工作规则。 首先,对于一门大语言,很难正确理解语法。 您将反复对其进行调整,以得到可以抽象使用的语法,然后必须调整编写的代码。 接下来,您会发现编写词法分析器也有麻烦。 只需尝试为Java编写词法分析器即可。 最后,您会发现解析器规则不是整个游戏,甚至不是您最大的努力。 您需要大量处理真实代码。 我称此为“解析后的生活”; 有关更多信息,请参见我的简历。
如果要每天获得150条工作规则,请切换到GLR解析器,然后手动停止对解析器进行编码。 那不会解决其他问题,但这确实使您在获得可用语法方面的工作异常出色。 这就是我现在要做的。 毫无例外。 (我们的DMS Software Reengineering Toolkit使用了此功能,并且我们分析了许多人们认为很难的事情。 )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.