ANTLR解析器问题

时间:2010-02-24 20:42:29

标签: antlr grammar

我正在尝试解析许多文本记录,其中记录中的元素由“+”字符分隔,并且整个记录以“#”字符结尾。例如E1 + E2 + E3 + E4 + E5 + E6#

可以要求或选择单个元素。如果一个元素是可选的,那么它的值就会丢失。例如,如果E2丢失,输入字符串将为:E1 ++ E3 + E4 + E5 + E6#。

但是,在处理空尾随元素时,也可能缺少分隔符char('+')。例如,如果缺少最后3个元素,则字符串可以是:E1 + E2 + E3#,但它也可以是: E1 + E2 + E3 +++#

我在Antlr中尝试了以下规则:

'R1''E1 + E2 + E3''+'? 'E4'? '+'? 'E5'? '+'? 'E6'? '#

但是Antlr抱怨它的含糊不清当然是正确的(E3之后的每个令牌都可能是E4,E5或E6)。输入语法是固定的(它来自传统的大型机系统),所以我想知道是否有人有这个问题的解决方案?

另一种方法是在规则中指定所有不同的排列,但这将是一项重大任务。

致以最诚挚的问候和谢谢,

迈克尔

2 个答案:

答案 0 :(得分:1)

对于ANTLR,这个任务听起来有点过分,你是不是因为没有使用'+'作为分隔符将字符串拆分成数组?

如果它来自大型机,它很可能是以一种微不足道的方式处理的。

如,
C ++:http://www.cplusplus.com/reference/clibrary/cstring/strtok/
PHP:http://us3.php.net/manual/en/function.explode.php
Java:http://java.sun.com/javase/6/docs/api/java/lang/String.html#split%28java.lang.String%29
C#:http://msdn.microsoft.com/en-us/library/system.string.split%28VS.71%29.aspx

只是一个想法。

答案 1 :(得分:0)

如果这是不明确的,可能是因为您的E具有相同的格式(更复杂的情况是您的E只是以相同的k个字符开头其中k是你的前瞻,但我会假设情况并非如此。如果是,这仍然可行;它只需要一个额外的步骤。)

所以看起来你最多可以有6 E秒和最多5 +秒。我们会说“细分”是一个可选的E,后跟一个+ - 您可以有5个细分,也可以选择尾随E

这个语法大致可以这样表示(不完美的ANTLR语法,因为我对它不是很熟悉):

r : (e_opt? PLUS){1,5} e_opt? END
e_opt : E  // whatever your E is
PLUS : '+'
END : '#'

如果ANTLR不支持{1,5}之类的内容,那么这与:

相同
(e_opt? PLUS) ((e_opt? PLUS) ((e_opt? PLUS) ((e_opt? PLUS) (e_opt? PLUS)?)?)?)?

这不是那么干净,所以也许有更好的方法可以做到。