对于具有左关联运算符的简单算术表达式,我有以下 EBNF 语法:
expression:
term {+ term}
term:
factor {* factor}
factor:
number
( expression )
如何在不改变运算符关联性的情况下将其转换为 BNF 语法?以下BNF语法对我不起作用,因为现在运算符已经变为右关联:
expression:
term
term + expression
term:
factor
factor * term
factor:
number
( expression )
维基百科说:
有几种解决方案:
- 重写语法以保留递归,或
- 使用更多非终结符号重写语法以强制使用正确的优先级/关联性,或者
- 如果使用YACC或Bison,则有运算符声明,%left,%right和%nonassoc,它们告诉解析器生成器强制哪个关联。
醇>
但它没有说如何重写语法,我不使用任何解析工具,如YACC或Bison,只是简单的递归下降。我甚至可能要求什么?
答案 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);