eclipse - 如何在 Eclipse 中使用 antlr4?

标签 eclipse antlr antlr4

由于 Antlr4 是 Antlr 的新版本,这是我第一次使用它。我已经从 eclipse 市场下载了 Antlr4 插件。
我做了新的 ANTLR 4 项目,我得到了 Hello.g4

后来我看到了这个小语法:

  /**
  * 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控制台看到它,我想测试程序但我不知道如何,我不知道如何制作一个可以由新编译的新文件语法?

在此先感谢您的帮助。

最佳答案

您需要创建生成的解析器的实例才能运行它。

  • 在您的 ANTLR 项目 A 旁边创建一个 Java 项目 J。
  • 在项目 J 中创建一个链接文件夹,引用generated-sources/antlr4 A 中的文件夹,并将此链接文件夹设为源
    文件夹。应该会出现编译错误。
  • 将 antlr4 jar 添加到项目 J 的构建路径中。这应该会消除编译错误。
  • 在 J 中编写一个主程序,它创建生成的实例
    解析器并用文本提供它。您可以从
    ANTLR 文档,为了方便贴在下面。

  • 必须通过传递语法名称( Hello ,在您的示例中)和起始规则( r )来调用 TestRig 。
    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) { }
          }
    }
    

    '希望这可以帮助!

    关于eclipse - 如何在 Eclipse 中使用 antlr4?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28352193/

    相关文章:

    antlr - "fragment"在ANTLR中是什么意思?

    java - 如何打开特定java进程的控制台

    eclipse - 如何使用Eclipse git merge工具进行 "ours"合并?

    java - 在 Eclipse 中禁用 "Chosen option is not enabled"消息

    regex - Antlr 解析器是贪婪的吗?

    debugging - ANTLRWorks 调试 - 不同颜色的含义?

    c - 在 Eclipse 的宏中无效使用宏粘贴

    java - ANTLR4 项目不会在 Eclipse 中显示任何内容

    antlr - 安装 Antlr v4.4 的问题

    antlr4 - 输入 ANTLR4 没有可行的替代方案?