左关联运算符的BNF语法

时间:2012-07-11 12:50:28

标签: parsing grammar bnf ebnf associativity

对于具有左关联运算符的简单算术表达式,我有以下 EBNF 语法:

expression:
    term {+ term}

term:
    factor {* factor}

factor:
    number
    ( expression )

如何在不改变运算符关联性的情况下将其转换为 BNF 语法?以下BNF语法对我不起作用,因为现在运算符已经变为右关联:

expression:
    term
    term + expression

term:
    factor
    factor * term

factor:
    number
    ( expression )

维基百科说:

  

有几种解决方案:

     
      
  1. 重写语法以保留递归,或
  2.   
  3. 使用更多非终结符号重写语法以强制使用正确的优先级/关联性,或者
  4.   
  5. 如果使用YACC或Bison,则有运算符声明,%left,%right和%nonassoc,它们告诉解析器生成器强制哪个关联。
  6.   

但它没有说如何重写语法,我不使用任何解析工具,如YACC或Bison,只是简单的递归下降。我甚至可能要求什么?

2 个答案:

答案 0 :(得分:10)

expression
    : term 
    | expression + term;

就这么简单。当然,您需要一些描述的LR解析器来识别左递归语法。或者,如果递归下降,识别这样的语法是可能的,但不像右关联语法那么简单。您必须滚动一个小的递归 ascent 解析器来匹配这样的。

Expression ParseExpr() {
    Expression term = ParseTerm();
    while(next_token_is_plus()) {
        consume_token();
        Term next = ParseTerm();
        term = PlusExpression(term, next);
    }
    return term;
}

这个伪代码应该识别该样式的左递归语法。

答案 1 :(得分:1)

Puppy建议的内容也可以通过以下语法表达:

     TransferManager.Configurations.ParallelOperations = 64;

         UploadDirectoryOptions options = new UploadDirectoryOptions()
                    {                              
                        ContentType = "image/jpeg",
                        Recursive = true,                   

                    };


    context.FileTransferred += FileTransferredCallback;
    context.FileFailed += FileFailedCallback;
    context.FileSkipped += FileSkippedCallback;


    await TransferManager.UploadDirectoryAsync(sourceDir, destDir, options:
 options, context: context, cancellationToken: cts.Token);