【问题标题】:How do I prioritize two overlapping expressions? (Ragel)如何确定两个重叠表达式的优先级? (拉格尔)
【发布时间】:2014-02-23 09:41:50
【问题描述】:

我有两种表达方式:

ident = alpha . (alnum|[._\-])*;
string = (printable1)+;
  # Printable includes almost all Windows-1252 characters with glyphs.
main := ( ident % do_ident | string % do_string )
  # The do_* actions have been defined, and generate tokens.

显然,任何 ident 都是一个字符串。 Ragel 有优先操作员来克服这个问题。但无论我如何尝试设置优先级,要么某些 ident 执行这两个操作,要么忽略某些有效字符串(以有效 ident 作为前缀的有效字符串,例如:ab$)。

我找到了一种不使用优先级的方法:

main := ( ident % do_ident | (string - ident) % do_string )

但是如果我有多个重叠的表达式,这会变得很麻烦。这是唯一可行的方法吗?

任何有关正确方法的帮助将不胜感激。

【问题讨论】:

  • 我和你有同样的问题。你找到一个好的答案吗?还是按照您的建议保留它?
  • 我最终采用了上面的方法,从低优先级的定义中减去了各种高优先级的定义。事实证明,我只需要对 14 种模式中的 4 种执行此操作。生成的代码并不漂亮,但它可以工作。

标签: ragel


【解决方案1】:

查看Ragel Guide 中的“6.3 扫描仪”部分

main := |*
    ident  => do_ident;
    string => do_string;
*|;

注意:使用扫描仪时,请在宿主语言中定义 tsteact

【讨论】:

  • Ragel 扫描仪的问题在于它们会根据 every 模式测试输入,以找到最长的匹配。但是对于带引号的字符串,我有 4 种模式,其中 3 种是默认值的真子集。每个字符串将针对 4 种模式进行检查,对于 3 种特殊情况,即对该字符串进行 2 次完整扫描。对于不带引号的字符串,有 6 个子模式,存在同样的问题。我可以消除其中的一些,但仍会存在重叠。我可以在没有扫描仪的情况下做到这一点,只是写起来有点麻烦。反对加倍的词法分析时间,我只需要花费更多的编码时间。 :(
  • 哇,真的扫描仪不适合你。我看不到您更大的项目,但我建议在单个机器实例中隔离重叠问题。然后,当您可以确定存在问题时,只需使用fholdfgoto 解决重叠问题,然后使用fret 跳回主机like in this example
  • 看看那个示例代码,这比我上面的减去模式的方法要多得多。到目前为止,我的图表有 54 个状态和 152 个转换。 Ragel 生成它的效果非常好,但我发现 Graphviz 看着它是可怕。 :P
  • 有关更多详细信息,我正在从类似于 JSON 的文件中读取数据,但绝对不是。我需要整数、带引号的整数、浮点数、日期(格式为 999.1.31)、带引号的日期、标识符、带引号的标识符、字符串、带引号的字符串、cmets(以 # 开头,运行到 EOL)和 '{'、'} '、'=' 符号。空格无关紧要,接受它可以分解其他标记。字符集是 Windows-1252,其中大部分对字符串和引号字符串有效。
【解决方案2】:

看起来你的问题是所有有效的标识符也是有效的字符串,如果可能的话,你只是希望它首先被解释为标识符。您可以通过在 ident 的离开操作中嵌入优先级来强制它首先接受标识符,这会覆盖字符串的所有转换:

main := ( ident %(ident_vs_string, 1) % do_ident | string $(ident_vs_string, 0) % do_string )

这将确保跟随有效表达式的离开转换停止机器探索继续或离开字符串。

注意这个组合表达式是如何终止的。标识符/字符串后面的任何表达式都必须以两者都不允许的字符开头,以便很好地定义退出转换。

【讨论】:

    猜你喜欢
    • 2017-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    • 1970-01-01
    • 1970-01-01
    • 2015-10-30
    相关资源
    最近更新 更多