【发布时间】:2018-06-26 17:02:46
【问题描述】:
我正在尝试消除歧义,与几天前的the question I asked 相同。在上一个问题中,语言实现存在未记录的限制;我想知道这里是否发生了类似的事情。
测试[tuvw]1 都在抛出歧义异常(顺便说一句:你如何捕捉到这些?[编辑:已回答])。他们看起来都应该通过。请注意,它们必须是明确的才能通过。优先规则Scheme 和保留规则UnknownScheme[23] 似乎都没有消除歧义。可能与我不理解的遵循规则有一些互动;这可能是另一个限制或缺陷。怎么了?
我在不稳定的分支上。版本(来自 Eclipse):0.10.0.201806220838
编辑。 我修改了示例代码以更清楚地突出显示正在发生的事情。我删除了一些多余的测试和行为正确的测试。我扩展了一些可能冗长的诊断。我更改了上面的说明以匹配。接下来是更新的结果。
看起来这里有两种不同的东西在起作用。在测试s1[ab] 中KnownScheme 和UnknownScheme 都(正确地)接受了"http"。似乎Scheme 中的优先级声明不起作用,好像> 被| 替换。
在另一种情况下,测试 s1[cde] 失败,但 s1f 正在通过。这看起来更像是一个缺陷。显然,可以保留一个关键字,但不能超过一个。由于各种保留声明都失败了,因此将其放入替代方案时会出现模棱两可的情况也就不足为奇了。
module ssce
import analysis::grammars::Ambiguity;
import IO;
lexical Scheme = AnyScheme ;
lexical AnyScheme = KnownScheme > UnknownScheme ;
lexical AnySchemeChar = [a-z*];
lexical KnownScheme = KnownSchemes !>> AnySchemeChar ;
lexical KnownSchemes = "http" | "https" | "http*" | "javascript" ;
lexical UnknownScheme = UnknownFixedScheme | UnknownWildScheme ;
lexical UnknownFixedScheme = [a-z]+ !>> AnySchemeChar ;
lexical UnknownWildScheme = [a-z]* '*' AnySchemeChar* !>> AnySchemeChar ;
lexical Scheme2 = UnknownScheme2 | KnownScheme ;
lexical UnknownScheme2 = UnknownScheme \ KnownSchemes ;
lexical Scheme3 = UnknownScheme3 | KnownScheme ;
lexical UnknownScheme3 = AnySchemeChar+ \ KnownSchemes ;
lexical Scheme4 = UnknownScheme4 | KnownScheme ;
lexical UnknownScheme4 = AnySchemeChar+ \ ("http"|"https") ;
lexical Scheme5 = UnknownScheme5 | KnownScheme ;
lexical UnknownScheme5 = AnySchemeChar+ \ "http" ;
test bool t1() { return parseAccept( #Scheme, "http" ); }
test bool u1() { return parseAccept( #Scheme2, "http" ); }
test bool v1() { return parseAccept( #Scheme3, "http" ); }
test bool w1() { return parseAccept( #Scheme4, "http" ); }
test bool x1() { return parseAccept( #Scheme5, "http" ); }
test bool s1a() { return parseAccept( #KnownScheme, "http" ); }
test bool s1b() { return parseAccept( #UnknownScheme, "http" ); }
test bool s1c() { return parseReject( #UnknownScheme2, "http" ); }
test bool s1d() { return parseReject( #UnknownScheme3, "http" ); }
test bool s1e() { return parseReject( #UnknownScheme4, "http" ); }
test bool s1f() { return parseReject( #UnknownScheme5, "http" ); }
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 "";
}
【问题讨论】:
-
我稍后再看看,可能在星期一。从远处看,它看起来像是一种难以诊断的常规模棱两可。同时,您可能会在 analysis::grammars::Ambiguity 中使用(古怪的)诊断工具。它会进行差异分析以猜测原因是什么以及如何解决它。
-
'catch Ambiguity(loc pos)' ,类似于解析错误。要使用诊断工具,您必须允许歧义
-
@jurgenv 感谢您的提示,但
catch Ambiguity(loc pos)不起作用。您需要catch Ambiguity(loc _, str _, str _)才能正确匹配参数列表。 -
@jurgenv 深入研究这个问题并获得新的示例代码。看起来这一个问题可能已经变成了两个缺陷报告。
-
抱歉让您久等了。我现在病了,所以很难集中注意力。希望答案对你有所帮助。
标签: rascal