首页 文章

在ANTLR中捕获“所有其他”字符

提问于
浏览
3

我正在尝试将ANTLR定义的语法集成到NetBeans中,到目前为止,有效的语法工作正常 . 但是,当前如果输入任何未在某处语言中定义的字符(例如,“?”字符),自定义编辑器会立即崩溃,因为它无法找到该字符的规则 .

在没有整个词法分析器崩溃和刻录的情况下,ANTLR中是否有一种方法可以捕获并跳过与规则不匹配的每个字符(并且可能输出错误消息)?我想标记无效字符,跳过它们,然后继续lexing,例如:

//some rules + tokens

invalidCharacter
    :    <<catch all other characters>>
        {System.out.println("undefined character entered!")}
    ;

任何帮助都会被批准 .

1 回答

  • 6

    如果你只对词法分析器中的非法字符感兴趣,那么这样简单的事情可能对你有所帮助:

    grammar T;
    
    @lexer::members {
      public List<String> errors = new ArrayList<String>();
    }
    
    parse
      :  .* EOF
      ;
    
    INT
      :  '0'..'9'+
      ;
    
    WORD
      :  ('a'..'z' | 'A'..'Z')+
      ;
    
    SPACE
      :  ' ' {$channel=HIDDEN;}
      ;
    
    INVALID
      :  . {
             errors.add("Invalid character: '" + $text + "' on line: " +
                 getLine() + ", index: " + getCharPositionInLine());
           }
      ;
    

    如您所见,只接受整数和ascii字,所有其他字符将导致错误被添加到词法分析器内的 List . 使用测试类解析类似 "abc 123 ? foo !" 的字符串时:

    import org.antlr.runtime.*;
    
    public class Main {
      public static void main(String[] args) throws Exception {
        TLexer lexer = new TLexer(new ANTLRStringStream("abc 123 ? foo !"));
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        tokens.toString(); // dummy call to toString() which causes all tokens to be created
        if(!lexer.errors.isEmpty()) {
          for(String error : lexer.errors) {
            System.out.println(error);
          }
        }
        else {
          TParser parser = new TParser(tokens);
          parser.parse();
        }
      }
    }
    

    将导致以下输出:

    java -cp antlr-3.3.jar org.antlr.Tool T.g
    javac -cp antlr-3.3.jar *.java
    java -cp .:antlr-3.3.jar Main
    
    Invalid character: '?' on line: 1, index: 9
    Invalid character: '!' on line: 1, index: 15
    

相关问题