【问题标题】:Catching "all other" characters in ANTLR在 ANTLR 中捕获“所有其他”字符
【发布时间】:2011-09-16 09:48:24
【问题描述】:

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

在 ANTLR 中是否有一种方法可以捕获并跳过每个与规则不匹配的字符(并可能输出错误消息),而不会导致整个词法分析器崩溃和烧毁?我只想标记无效字符,跳过它们,然后继续进行词法分析,例如:

//some rules + tokens

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

如有任何帮助,将不胜感激。

【问题讨论】:

    标签: antlr grammar character lexer


    【解决方案1】:

    如果您只对词法分析器中的非法字符感兴趣,那么简单的方法可能会为您解决问题:

    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 主要 无效字符: '?'上线:1,索引:9 无效字符: '!'上线:1,索引:15

    【讨论】:

    • 这对于孤立的字符似乎工作得很好,但如果你有很多它们串在一起它会失败......例如输入“!!!!????~~~~”跨度>
    • @donnyton,好吧,对于n 无效字符,它会创建n 不同的消息。如果那不是你想要的,你需要多解释一下自己。
    • 当我尝试将新语法集成到 NetBeans 中时,它会正确检测单个无效击键,但当我复制粘贴许多无效字符或打开包含许多无效字符的文件时会崩溃。但是,我想出了一个解决方案——将 INVALID 定义为一个片段,并制定一个“invalidSequence”规则来更深入地处理它们。
    猜你喜欢
    • 1970-01-01
    • 2012-09-11
    • 2016-12-29
    • 2012-04-12
    • 2022-11-22
    • 2018-10-22
    • 1970-01-01
    • 1970-01-01
    • 2021-03-03
    相关资源
    最近更新 更多