如何使用ANTLR语法排除字符/符号?

时间:2010-07-09 10:06:44

标签: antlr antlr3

我正在尝试使用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,: - ”

2 个答案:

答案 0 :(得分:5)

  

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

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

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

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

但是你可能想要发表你的整个语法:我得到的印象是你应该做的其他一些你没有做的事情。你的电话。

答案 1 :(得分:2)

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

对于unicode,这可能是这样的:

 UTF8 :  ('\u0000'..'\u002A'     // ! to * 
     | '\u002E'..'\u002F'           // . / 
     | '\u003B'..'\u00FF'           // ; < = > ? @ as well as letters brackets and stuff
     ) 
     ;