4

我正在尝试使用 ANTLR 为各种时间格式(12:30、0945、1:30-2:45,...)编写语法。到目前为止,只要我不输入语法文件中未定义的字符,它就像一个魅力。

例如,我正在使用以下 JUnit 测试:

    final CharStream stream = new ANTLRStringStream("12:40-1300,15:123-18:59");
    final TimeGrammarLexer lexer = new TimeGrammarLexer(stream);
    final CommonTokenStream tokenStream = new CommonTokenStream(lexer);
    final TimeGrammarParser parser = new TimeGrammarParser(tokenStream);

    try {
        final timeGrammar_return tree = parser.timeGrammar();
        fail();
    } catch (final Exception e) {
        assertNotNull(e);
    }

抛出异常(如预期),因为“15:123”无效。但是,如果我尝试 ("15:23a"),则不会引发异常,并且 ANTLR 将其视为有效输入。

现在,如果我在语法中定义字符,ANTLR 似乎会注意到它们,并且我再次得到我想要的异常:

  CHAR: ('a'..'z')|('A'..'Z');

但是如何排除变音符号、符号和其他用户可以输入的内容(äöü{%&<>!)。所以基本上我正在寻找某种语法说:匹配所有内容但“0..9,:-”

4

2 回答 2

5

...
所以基本上我正在寻找某种语法说:匹配所有内容但"0..9,:-"

以下规则匹配除数字、 和 之外的任何,单个:字符-

Foo
  :  ~('0'..'9' | ',' | ':' | '-')
  ;

~词法分析器规则中的否定单个字符)

但是你可能想发布你的整个语法:我觉得还有一些其他的事情你没有做,因为他们应该做的。你的来电。

于 2010-07-12T18:27:39.260 回答
2

您可以定义一个与您不想要的所有字符匹配的文字。如果您的任何规则中都不包含此文字,则 antlr 将抛出 NonViableException。

对于 unicode,这可能如下所示:

 UTF8 :  ('\u0000'..'\u002A'     // ! to * 
     | '\u002E'..'\u002F'           // . / 
     | '\u003B'..'\u00FF'           // ; < = > ? @ as well as letters brackets and stuff
     ) 
     ;
于 2010-07-09T10:07:52.107 回答