繁体   English   中英

EBNF产品的预测解析器

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM