该储备金声明难理解还是有缺陷?

时间:2018-06-21 16:58:38

标签: rascal

使用保留(反斜杠)声明进行优先级歧义处理时遇到问题。以下是一个独立的示例。生产“ Ipv4Address”是“ Domain0”的严格子集。但是,在解析URL时,您希望对点分四进制地址的处理与对域名的处理不同,因此,您希望将“ Domain0”分为两部分: “ Domain1”是这两个部分之一。但是,其中包含的测试套件在“ t3()”处失败,其中“ Domain1”正在接受IP地址,看来应该将其排除在外。

这是储备金声明的问题,还是当前Rascal版本中的缺陷?根据建议,我目前位于0.10.x不稳定分支上,以查看这是否纠正了另一个问题(使用Tutor)。我没有检查过稳定分支,因为同时安装这两个分支意味着并行的Eclipse环境,而我并没有动机去做。

module grammar_test

import ParseTree;

syntax Domain0 = { Subdomain '.' }+;
syntax Domain1 = Domain0 \ IPv4Address ;
lexical Subdomain = [0-9A-Za-z]+ | [0-9A-Za-z]+'-'[a-zA-Z0-9\-]*[a-zA-Z0-9] ;
lexical IPv4Address = DecimalOctet '.' DecimalOctet '.' DecimalOctet '.' DecimalOctet ; 
lexical DecimalOctet = [0-9] | [1-9][0-9] | '1'[0-9][0-9] | '2'[0-4][0-9] | '25'[0-5] ;

test bool t1()
{
    return parseAccept(#IPv4Address, "192.168.0.1");
}   

test bool t2()
{
    return parseAccept(#Domain0, "192.168.0.1");
}   

test bool t3()
{
    return parseReject(#Domain1, "192.168.0.1");
}   

bool parseAccept( type[&T<:Tree] begin, str input )
{
    try
    {
        parse(begin, input, allowAmbiguity=false);
    }
    catch ParseError(loc _):
    {
        return false;
    }
    return true;
}

bool parseReject( type[&T<:Tree] begin, str input )
{
    try
    {
        parse(begin, input, allowAmbiguity=false);
    }
    catch ParseError(loc _):
    {
        return true;
    }
    return false;
}

此示例已从较大的代码中删减。我首先在较大范围内遇到了该错误。使用规则“ IPv4Address | Domain1”引发了歧义异常,我追溯到“ Domain1”正在接受它不应该接受的行为。奇怪的是,“ IPv4Address> Domain1”也引发了歧义,但我猜想这与当前隔离的示例具有相同的根本原因。

1 个答案:

答案 0 :(得分:1)

关键字保留的差分运算符当前仅在右侧是表示为诸如"if" | "then" | "while"之类的文字关键字或定义为以下形式的非终结符的析取词的有限语言时才能正确工作: } A \ X`。

对于其他类型的非终结符,仅生成了解析器,但是lexical X = "if" | "then" | "while". And then you can write约束无效。您写了\,但IPv3Address不符合上述假设。

(我们应该对此添加警告,或者生成一个解析器,该解析器可以实现语言差异的完整语义;但这是另一次)。

诚然,可以使用这种功能强大的差异算子来表示非终端之间的某些优先顺序。 las。

可能的解决方案:

  • 第二阶段遍历解决方案:使用更通用的Domain0 \ IPv4Address语法解析输入,然后在一次遍历中将所有四倍变为IPv4Address进行模式匹配匹配重写
  • 最大的munch解决方案:使用遵循限制来适应语法,以实现IPv4Address的急切行为,例如Subdomain或徒劳的行为。