【发布时间】:2018-07-10 20:35:14
【问题描述】:
在我的previous question 中,示例中有一个优先级> 声明。事实证明这并不重要,因为那里的解决方案实际上并没有调用优先级,而是通过使替代方案脱节来避免它。在这个问题中,我在问是否可以使用优先级来选择一个词汇产生而不是另一个。在下面的示例中,产生式WordInitialDigit 的语言故意是WordAny 的语言的子集。产生式Word 看起来应该正确地消除两者之间的歧义,但生成的解析树在顶部有一个歧义节点。优先声明是否能够在不同的词汇缩减之间做出决定,还是需要有共同词汇元素的基础?还是别的什么?
这个例子是人为的(语法中没有动作),但它产生的情况不是。例如,我想使用这样的东西来进行错误恢复,我可以识别语法单元的自然边界并为其编写产生式。这种通用生产将是优先链中的最后一个元素;如果它减少,则意味着没有有效的解析。更一般地说,我需要能够根据句法上下文选择词汇元素。我曾希望,因为 Rascal 没有扫描仪,所以这将是无缝的。也许是吧,虽然我现在没看到。
我在不稳定的分支上,版本 0.10.0.201807050853。
编辑:这个问题不是关于> 用于定义表达式语法。 documentation for priority declarations 主要谈论表达式,但第一句话提供了一个看起来非常清晰的定义:
优先级声明定义了在单个非终结符中的产生之间的部分排序。
所以这个例子有两个产生式,它们之间声明了一个排序,但是解析器仍然在明确存在消歧规则的情况下生成一个歧义节点。因此,为了更好地说明我的问题,看起来我不知道两种情况中的哪一种有关。 (1)如果这不应该工作,那么文档中的语言定义存在缺陷,编译器错误报告的缺陷,以及介于违反直觉和用户敌意之间的语言设计决策。或者 (2) 如果这应该可以工作,那么编译器和/或解析器中存在缺陷(可能是因为最初关注的是表达式),并且在某些时候该示例将通过其测试。
module ssce
import analysis::grammars::Ambiguity;
import ParseTree;
import IO;
import String;
lexical WordChar = [0-9A-Za-z] ;
lexical Digit = [0-9] ;
lexical WordInitialDigit = Digit WordChar* !>> WordChar;
lexical WordAny = WordChar+ !>> WordChar;
syntax Word =
WordInitialDigit
> WordAny
;
test bool WordInitialDigit_0() = parseAccept( #Word, "4foo" );
test bool WordInitialDigit_1() = parseAccept( #WordInitialDigit, "4foo" );
test bool WordInitialDigit_2() = parseAccept( #WordAny, "4foo" );
bool verbose = false;
bool parseAccept( type[&T<:Tree] begin, str input )
{
try
{
parse(begin, input, allowAmbiguity=false);
}
catch ParseError(loc _):
{
return false;
}
catch Ambiguity(loc l, str a, str b):
{
if (verbose)
{
println("[Ambiguity] #<a>, \"<b>\"");
Tree tt = parse(begin, input, allowAmbiguity=true) ;
iprintln(tt);
list[Message] m = diagnose(tt) ;
println( ToString(m) );
}
fail;
}
return true;
}
bool parseReject( type[&T<:Tree] begin, str input )
{
try
{
parse(begin, input, allowAmbiguity=false);
}
catch ParseError(loc _):
{
return true;
}
return false;
}
str ToString( list[Message] msgs ) =
( ToString( msgs[0] ) | it + "\n" + ToString(m) | m <- msgs[1..] );
str ToString( Message msg)
{
switch(msg)
{
case error(str s, loc _): return "error: " + s;
case warning(str s, loc _): return "warning: " + s;
case info(str s, loc _): return "info: " + s;
}
return "";
}
【问题讨论】:
-
我可以从你的描述中看出你是如何被引导认为相同非终结符的备选方案之间的规则选择直接受优先级排序的影响。但事实并非如此。从优先级声明生成的部分顺序定义了排除某种嵌套的约束,即加法规则不会在乘法规则下扩展。我们应该更改文档以避免这种解释。
标签: rascal