【发布时间】:2020-02-07 14:42:33
【问题描述】:
我想写一个具体的语法来解析类似 BNF 的语法定义。
查看EXP Concrete Syntax 配方,我创建了这个非常简单的第一个版本:
module BNFParser
lexical Identifier = [a-z]+ ;
syntax GrammarRule = left RuleHead ":" RuleCase* ";" ;
syntax RuleHead = Identifier ;
syntax RuleCase = Identifier ;
并像这样在 Repl 中调用它:
import BNFParser;
import ParseTree;
parse(#GrammarRule, "foo : bar baz ;");
但这会导致一个相当晦涩的错误消息:
|std:///ParseTree.rsc|(13035,1963,<393,0>,<439,114>): ParseError(|unknown:///|(3,1,<1,3>,<1,4>))
at *** somewhere ***(|std:///ParseTree.rsc|(13035,1963,<393,0>,<439,114>))
at parse(|std:///ParseTree.rsc|(14991,5,<439,107>,<439,112>))
ok
我也尝试在 GrammarRule 之前使用 start 关键字,但这没有帮助。我做错了什么?
【问题讨论】:
-
嗨,托马斯;您可能缺少所有其余部分之间的空白和 cmets 的布局定义?
-
太好了,感谢您的快速回复。这有帮助。我仍然在 Kleene 星
RuleCase*上收到Ambiquity错误。与+相同。把两者都放在一边,我可以解析foo : bar;ok。 -
永远不要将 * 列表直接嵌套在 + 列表中,这会导致循环规则(因此也会产生歧义)。此外,对于标识符列表,您需要通过在标识符词法规则的末尾添加
!>> [a-z]来声明最长匹配。它说规则不应该减少,除非没有更多的 a 到 z 可以消费。 Rascal 不像其他解析器/词法分析器生成器那样做启发式或隐式消歧。你必须宣布这一切,但你确切地知道你在处理什么???? -
是的,感谢 Jurgen,修复了它。我刚刚在
SyntaxDefinition概念页面中遇到了同样的提示:-)。 - 来吧,做一个两行答案,这样我就可以投票并接受它。