Поймать всех остальных персонажей в ANTLR - PullRequest
3 голосов
/ 16 июня 2011

Я пытаюсь интегрировать грамматику ANTLR в NetBeans, и пока действительный синтаксис работает нормально. Однако в настоящее время, если вы вводите какой-либо символ, который не определен в каком-либо языке (например, символ «?»), Пользовательский редактор немедленно падает, поскольку не может найти правило для этого символа.

Есть ли в ANTLR способ перехватить и пропустить КАЖДЫЙ символ, который не соответствует правилу (и, возможно, вывести сообщение об ошибке), не вызывая крах и сгорание всего лексера? Я хотел бы просто отметить недопустимые символы, пропустить их и продолжить лексизм, что-то вроде:

//some rules + tokens

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

Любая помощь будет оценена.

1 Ответ

6 голосов
/ 16 июня 2011

Если вас интересуют только нелегальные символы внутри лексера, что-то простое может помочь вам:

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
...