我使用Ragel实现了一个非常简单的解析器。 “主要”结构是扫描仪。
我实现了类似的东西:
action doSomething
{
doSomething(fpc);
}
foo = 'foo';
bar = 'bar';
main := |*
foo => { matchFoo(); };
bar => { matchBar(); };
space;
*|;
如何匹配其他规则不匹配的其他规则(即基本上是错误条件,某种格式错误的输入)?我想实现它,以便能够在格式错误的输入的哪一行上出错。我尝试在扫描仪的末尾使用“任何”条件但当然不起作用,因为这将始终是“最长匹配”,因此扫描仪每次都会匹配它。我肯定不想从包含所有其他令牌的列表中取一些否定(从'any'中排除它们),因为这听起来很错误(难以维护并最终成为包含许多令牌的大量代码) 。如何匹配Ragel扫描仪中与其他东西不匹配的其他内容?
编辑:做了一些测试,如果我只是在扫描仪的末尾匹配“任何”,我可以让它工作。然后当角色不匹配时它将转到该表达式。但是,如果我尝试匹配“任何+”,那么它将不起作用,因为它将每次都去那里(对于所有数据,它将始终是扫描仪中最长的匹配)。只匹配“any”的问题是我没有得到令牌开始和令牌结束指针到WHOLE连续块的不匹配数据。如何匹配“与其他任何内容不匹配的最长连续字符块”?
答案 0 :(得分: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;
*|;
通过将gs
与pe
进行比较,您还必须在Ragel完成后检查输入结尾处的垃圾。
请注意,我还没有测试过这台机器,但是我已经通过Ragel运行了它,并查看了机器的GraphViz图表。