【问题标题】:Rascal: Grammar to Parse BNFRascal:解析 BNF 的语法
【发布时间】: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。
  • 永远不要将 * 列表直接嵌套在 + 列表中,这会导致循环规则(因此也会产生歧义)。此外,对于标识符列表,您需要通过在标识符词法规则的末尾添加 !&gt;&gt; [a-z] 来声明最长匹配。它说规则不应该减少,除非没有更多的 a 到 z 可以消费。 Rascal 不像其他解析器/词法分析器生成器那样做启发式或隐式消歧。你必须宣布这一切,但你确切地知道你在处理什么????
  • 是的,感谢 Jurgen,修复了它。我刚刚在SyntaxDefinition 概念页面中遇到了同样的提示:-)。 - 来吧,做一个两行答案,这样我就可以投票并接受它。

标签: grammar rascal


【解决方案1】:
lexical Identifier = [a-z]+ !>> [a-z];

这有助于识别不明确的列表。附加的 !>> 约束声明标识符只有在不能使用更多字符时才可接受。

这也是修复解析错误所必需的:

layout Whitespace = [\ \n\r]*;

对于范围内的所有语法规则,它将在所有符号之间混合此非终结符。它只留下词汇规则。

【讨论】:

  • 真正让我印象深刻的是——如果我做对了——在 EXP 配方的 eval 函数中,您在解析树上使用 树模式匹配 来区分函数子句......哇。
  • ? 我也喜欢 Rascal;尽管具体的树模式匹配和构造功能可能需要更多的爱才能使其达到 Rascal 的前身 (ASF+SDF) 的可用性水平。我们现在首先在做别的事情,那就是 Rascal 静态检查器和编译器。敬请期待!
猜你喜欢
  • 2013-01-05
  • 2021-07-16
  • 1970-01-01
  • 2011-11-15
  • 1970-01-01
  • 2011-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多