0

我有一个非常简单的 ANTLR 语法,我正在尝试开始工作,但目前失败得很惨。真的很感激这方面的一些指示......

root    :   (keyword|ignore)*;
keyword :    KEYWORD;
ignore  :    IGNORE;

KEYWORD : ABBRV|WORD;   

fragment WORD : ALPHA+;
fragment ALPHA : 'a'..'z'|'A'..'Z';
fragment ABBRV : WORD?('.'WORD);

IGNORE  : .{ Skip(); };

使用以下测试输入:

"some ASP.NET and .NET stuff. that work."

我想要一棵只是关键字节点列表的树,

"some", "ASP.NET", "and", ".NET", "stuff", "that", "work"

此刻我得到

"some", "ASP.NET", "and", ".NET", "stuff. that",

(由于某种原因“。”出现在最后一个关键字中,它错过了“工作”

如果我将 ABBRV 子句更改为

fragment ABBRV : ('.'WORD);

然后效果很好,但我得到关键字(asp)和关键字(.net) - 分开 - 但我需要它们作为一个单一的标记。

您可以提供的任何帮助将不胜感激。

4

2 回答 2

0

有几件事,首先你的忽略解析器规则永远不会被触发,甚至不必出现在这个语法中(也排除在根规则之外)。当然,由于您正在调试并且具有忽略规则,因此测试起来要容易得多(通过在 IGNORE 词法分析器规则中删除 skip(); )。

现在解释测试数据,因为没有一个词法分析器标记只匹配 WORD '.' 由于文本后面的句点,您的测试数据的结尾被忽略了。如果你在“工作”和句号之间放置一个空格,那么最后一个单词会出现,句号不会出现,这就是你想要的。词法分析器不知道如何处理“工作”。当它结束时。如果您在末尾添加另一个单词(在句点和新单词之间添加一个空格),则“工作”。作为一个 IGNORE 令牌从词法分析器规则传递。我原以为这个词会通过,句号应该只在 IGNORE 标记中。

于 2010-02-05T03:45:10.687 回答
0

我决定尝试使用 ANTLR3 语法解决您的问题。这就是我想出的,附带一些条件:

  • 您的规范不包含很多规则,因此,我的语法不是很彻底。
  • 考虑添加到 KEYW 以匹配更多令牌。
  • 我现在没有 C# 兼容的 ANTLR。大写“skip()”以使其兼容。

    grammar TestSplitter;
    
    start: (KEYW DELIM!?)* ;
    KEYW: ('a'..'z'|'A'..'Z'|'.')+ ;
    DELIM: '.'? ' '+ ;
    
于 2010-02-26T07:35:28.430 回答