2015-02-05 60 views
2

由於Antlr4是Antlr的新版本,這是我第一次使用它。我已經從eclipse marketplace下載了Antlr4插件。 我提出了新的ANTLR 4項目,我Hello.g4如何在Eclipse中使用antlr4?

後來我看到這個小的語法:

/** 
    * Define a grammar called Hello 
    */ 
    grammar Hello; 
    r : 'hello' ID ;   // match keyword hello followed by an               identifier 

     ID : [a-z]+ ;    // match lower-case identifiers 

     WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines 

一旦它被保存,這是構建和我看到它從ANTLR的控制檯,我想測試程序,但我不知道如何,我不知道如何創建一個新的文件,可以通過新的語法編譯?

在此先感謝您的幫助。

回答

4

您需要創建生成的解析器的實例才能運行它。

  • 創建一個Java項目J下你ANTLR項目A.
  • 創建項目J A鏈接的文件夾引用從A generated-sources/antlr4文件夾,使這個鏈接文件夾源 文件夾。應該出現編譯錯誤。
  • 將antlr4 jar添加到項目J的構建路徑。這應該消除編譯錯誤。
  • 在J中編寫一個主程序,該程序創建生成的 解析器的一個實例並用文本提供它。您可以從 ANTLR文檔中獲取TestRig,以便粘貼到下面。

的TestRig必須通過語法名稱(你好,在你的例子),並開始規則([R)被調用。

import org.antlr.v4.runtime.ANTLRInputStream; 
import org.antlr.v4.runtime.CharStream; 
import org.antlr.v4.runtime.CommonTokenStream; 
import org.antlr.v4.runtime.DefaultErrorStrategy; 
import org.antlr.v4.runtime.DiagnosticErrorListener; 
import org.antlr.v4.runtime.InputMismatchException; 
import org.antlr.v4.runtime.Lexer; 
import org.antlr.v4.runtime.Parser; 
import org.antlr.v4.runtime.ParserRuleContext; 
import org.antlr.v4.runtime.RecognitionException; 
import org.antlr.v4.runtime.Token; 
import org.antlr.v4.runtime.TokenStream; 
import org.antlr.v4.runtime.atn.PredictionMode; 

import javax.print.PrintException; 

import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.Reader; 
import java.lang.reflect.Constructor; 
import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import java.util.ArrayList; 
import java.util.List; 

/** Run a lexer/parser combo, optionally printing tree string or generating 
* postscript file. Optionally taking input file. 
* 
* $ java org.antlr.v4.runtime.misc.TestRig GrammarName startRuleName 
*  [-tree] 
*  [-tokens] [-gui] [-ps file.ps] 
*  [-trace] 
*  [-diagnostics] 
*  [-SLL] 
*  [input-filename(s)] 
*/ 
public class Test { 
    public static final String LEXER_START_RULE_NAME = "tokens"; 

    protected String grammarName; 
    protected String startRuleName; 
    protected final List<String> inputFiles = new ArrayList<String>(); 
    protected boolean printTree = false; 
    protected boolean gui = false; 
    protected String psFile = null; 
    protected boolean showTokens = false; 
    protected boolean trace = false; 
    protected boolean diagnostics = false; 
    protected String encoding = null; 
    protected boolean SLL = false; 

    public Test(String[] args) throws Exception { 
     if (args.length < 2) { 
      System.err.println("java org.antlr.v4.runtime.misc.TestRig GrammarName startRuleName\n" + 
           " [-tokens] [-tree] [-gui] [-ps file.ps] [-encoding encodingname]\n" + 
           " [-trace] [-diagnostics] [-SLL]\n"+ 
           " [input-filename(s)]"); 
      System.err.println("Use startRuleName='tokens' if GrammarName is a lexer grammar."); 
      System.err.println("Omitting input-filename makes rig read from stdin."); 
      return; 
     } 
     int i=0; 
     grammarName = args[i]; 
     i++; 
     startRuleName = args[i]; 
     i++; 
     while (i<args.length) { 
      String arg = args[i]; 
      i++; 
      if (arg.charAt(0)!='-') { // input file name 
       inputFiles.add(arg); 
       continue; 
      } 
      if (arg.equals("-tree")) { 
       printTree = true; 
      } 
      if (arg.equals("-gui")) { 
       gui = true; 
      } 
      if (arg.equals("-tokens")) { 
       showTokens = true; 
      } 
      else if (arg.equals("-trace")) { 
       trace = true; 
      } 
      else if (arg.equals("-SLL")) { 
       SLL = true; 
      } 
      else if (arg.equals("-diagnostics")) { 
       diagnostics = true; 
      } 
      else if (arg.equals("-encoding")) { 
       if (i>=args.length) { 
        System.err.println("missing encoding on -encoding"); 
        return; 
       } 
       encoding = args[i]; 
       i++; 
      } 
      else if (arg.equals("-ps")) { 
       if (i>=args.length) { 
        System.err.println("missing filename on -ps"); 
        return; 
       } 
       psFile = args[i]; 
       i++; 
      } 
     } 
    } 

    public static void main(String[] args) throws Exception { 
     Test test = new Test(args); 
     if(args.length >= 2) { 
      test.process(); 
     } 
    } 

    public void process() throws Exception { 
     //System.out.println("exec "+grammarName+" "+startRuleName); 
     String lexerName = grammarName+"Lexer"; 
     ClassLoader cl = Thread.currentThread().getContextClassLoader(); 
     Class<? extends Lexer> lexerClass = null; 
     try { 
      lexerClass = cl.loadClass(lexerName).asSubclass(Lexer.class); 
     } 
     catch (java.lang.ClassNotFoundException cnfe) { 
       System.err.println("1: Can't load "+lexerName+" as lexer or parser"); 
       return; 
     } 

     Constructor<? extends Lexer> lexerCtor = lexerClass.getConstructor(CharStream.class); 
     Lexer lexer = lexerCtor.newInstance((CharStream)null); 

     Class<? extends Parser> parserClass = null; 
     Parser parser = null; 
     if (!startRuleName.equals(LEXER_START_RULE_NAME)) { 
      String parserName = grammarName+"Parser"; 
      parserClass = cl.loadClass(parserName).asSubclass(Parser.class); 
      if (parserClass==null) { 
       System.err.println("Can't load "+parserName); 
      } 
      Constructor<? extends Parser> parserCtor = parserClass.getConstructor(TokenStream.class); 
      parser = parserCtor.newInstance((TokenStream)null); 
     } 

     if (inputFiles.size()==0) { 
      InputStream is = System.in; 
      Reader r; 
      if (encoding!=null) { 
       r = new InputStreamReader(is, encoding); 
      } 
      else { 
       r = new InputStreamReader(is); 
      } 

      process(lexer, parserClass, parser, is, r); 
      return; 
     } 
     for (String inputFile : inputFiles) { 
      InputStream is = System.in; 
      if (inputFile!=null) { 
       is = new FileInputStream(inputFile); 
      } 
      Reader r; 
      if (encoding!=null) { 
       r = new InputStreamReader(is, encoding); 
      } 
      else { 
       r = new InputStreamReader(is); 
      } 

      if (inputFiles.size()>1) { 
       System.err.println(inputFile); 
      } 
      process(lexer, parserClass, parser, is, r); 
     } 
    } 

    protected void process(Lexer lexer, Class<? extends Parser> parserClass, Parser parser, InputStream is, Reader r) throws IOException, IllegalAccessException, InvocationTargetException, PrintException { 
     try { 
      ANTLRInputStream input = new ANTLRInputStream(r); 
      lexer.setInputStream(input); 
      CommonTokenStream tokens = new CommonTokenStream(lexer); 

      tokens.fill(); 

      if (showTokens) { 
       for (Object tok : tokens.getTokens()) { 
        System.out.println(tok); 
       } 
      } 

      if (startRuleName.equals(LEXER_START_RULE_NAME)) return; 

      if (diagnostics) { 
       parser.addErrorListener(new DiagnosticErrorListener()); 
       parser.getInterpreter().setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION); 
      } 

      if (printTree || gui || psFile!=null) { 
       parser.setBuildParseTree(true); 
      } 

      if (SLL) { // overrides diagnostics 
       parser.getInterpreter().setPredictionMode(PredictionMode.SLL); 
      } 

      parser.setTokenStream(tokens); 
      parser.setTrace(trace); 
      //parser.setErrorHandler(new BailErrorStrategy()); 

      try { 
       Method startRule = parserClass.getMethod(startRuleName); 
       ParserRuleContext tree = (ParserRuleContext)startRule.invoke(parser, (Object[])null); 

       if (printTree) { 
        System.out.println(tree.toStringTree(parser)); 
       } 
       if (gui) { 
        tree.inspect(parser); 
       } 
       if (psFile!=null) { 
        tree.save(parser, psFile); // Generate postscript 
       } 
      } 
      catch (NoSuchMethodException nsme) { 
       System.err.println("No method for rule "+startRuleName+" or it has arguments"); 
      } 
     } 
     finally { 
      if (r!=null) r.close(); 
      if (is!=null) is.close(); 
     } 
    } 

    @SuppressWarnings("unused") 
    private static class BailErrorStrategy extends DefaultErrorStrategy { 
     /** Instead of recovering from exception e, rethrow it wrapped 
     * in a generic RuntimeException so it is not caught by the 
     * rule function catches. Exception e is the "cause" of the 
     * RuntimeException. 
     */ 
     @Override 
     public void recover(Parser recognizer, RecognitionException e) { 
     throw new RuntimeException(e); 
     } 
     /** Make sure we don't attempt to recover inline; if the parser 
     * successfully recovers, it won't throw an exception. 
     */ 
     @Override 
     public Token recoverInline(Parser recognizer) 
     throws RecognitionException 
     { 
     throw new RuntimeException(new InputMismatchException(recognizer)); 
     } 
     /** Make sure we don't attempt to recover from problems in subrules. */ 
     @Override 
     public void sync(Parser recognizer) { } 
     } 
} 

'希望這會有所幫助!

+0

謝謝你,但我從控制檯運行時錯誤,說: 的Java org.antlr.v4.runtime.misc.TestRig GrammarName startRuleName [-tokens] [ - 樹] [-gui] [-PS文件。 ps] [-encoding encodingname] [-trace] [-diagnostics] [-SLL] [input-filename(s)] 如果GrammarName是詞法分析器語法,則使用startRuleName ='tokens'。 忽略輸入文件名使鑽塔從標準輸入讀取。 – 2015-02-06 21:32:53

+0

你提供了命令行參數嗎?在Eclipse中,「運行配置」窗口有一個「(x)參數」選項卡,其中有一個「程序參數」字段,您可以在其中提供命令行參數。在你的情況下,你可能需要:'你好r <你的文件名>'。 – 2015-02-09 08:55:48