1

我已经使用 Ragel 实现了一个非常简单的解析器。“主要”结构是扫描仪。

我有这样的实现:

action doSomething
{
    doSomething(fpc);
}

foo = 'foo';
bar = 'bar';

main := |*

    foo => { matchFoo(); };
    bar => { matchBar(); };
    space;

*|;

我如何匹配其他规则不匹配的所有其他内容(即基本上是错误条件,某种格式错误的输入)?我想实现它以便能够在格式错误的输入所在的行上得到错误。我尝试在扫描仪末尾使用“任何”条件,但这当然不起作用,因为这将始终是“最长匹配”,因此扫描仪每次都会匹配它。我绝对不想从包含所有其他标记的列表中进行某种否定(以将它们从“任何”中排除),因为这听起来是错误的(难以维护并且最终成为带有许多标记的大块代码) . 如何在 Ragel 的扫描仪中匹配与其他东西不匹配的所有其他内容?

编辑:做了一些测试,如果我在扫描仪末尾匹配“任何”,我就可以让它工作。然后,当字符不匹配时,它将转到该表达式。但是,如果我尝试匹配“any+”,那么它将不起作用,因为它每次都会去那里(对于所有数据,它始终是扫描仪中最长的匹配项)。仅匹配“任何”的问题是我没有将令牌开始和令牌结束指针指向整个不匹配数据的连续块。如何匹配“不匹配任何其他字符的最长连续字符块”?

4

1 回答 1

1

我会跟踪我的有效输入何时结束,并将其与新的有效输入何时开始进行比较。因此,介于两者之间的任何内容都是无效的。像这样的东西:

foo = 'foo';
bar = 'bar';

action doFoo {
    if (ts > gs) handleError();
    gs = te;
    matchFoo();
}

action doBar {
    if (ts > gs) handleError();
    gs = te; 
    matchBar();
}

action doSpace {
    if (ts > gs) handleError();
    gs = te;
}

main := |*

    foo =>   doFoo;
    bar =>   doBar;
    space => doSpace;
    any;

*|;

在 Ragel 完成后,您还必须在输入结束时通过gspe.

请注意,我没有测试过这台机器,但我已经通过 Ragel 运行它并查看了机器的 GraphViz 图。

于 2016-01-08T19:26:40.863 回答