2015-10-02 2 views
3

Я знаю, что большинство людей позволяет Antlr генерировать из командной строки, но я хотел бы назвать его с Java. Я также не могу назвать main класса Tool, так как этот класс использует System.exit, так как это также выходит из моей программы.Генерировать Antlr4 Lexer с Java

То, что я пытался до сих пор следующие:

 String g4Content = "My Grammar Content";    

     String[] arg0 = {pathOfG4File, "-package", "mypackage"}; 

     Tool tool = new Tool(arg0); 

     GrammarRootAST ast = tool.parseGrammarFromString(g4Content) 
     Grammar grammar = tool.createGrammar(ast); 

     tool.process(grammar, true) 

я получаю следующее исключение:

java.lang.NoSuchMethodError: org.antlr.v4.parse.BlockSetTransformer.inContext(Ljava/lang/String;)Z 
at org.antlr.v4.parse.BlockSetTransformer.setAlt(BlockSetTransformer.java:467) 
at org.antlr.v4.parse.BlockSetTransformer.topdown(BlockSetTransformer.java:370) 
at org.antlr.v4.parse.BlockSetTransformer.topdown(BlockSetTransformer.java:24) 
at org.antlr.runtime.tree.TreeRewriter$2.rule(TreeRewriter.java:108) 
at org.antlr.runtime.tree.TreeRewriter.applyOnce(TreeRewriter.java:61) 
at org.antlr.runtime.tree.TreeRewriter$1.pre(TreeRewriter.java:92) 
at org.antlr.runtime.tree.TreeVisitor.visit(TreeVisitor.java:28) 
at org.antlr.runtime.tree.TreeVisitor.visit(TreeVisitor.java:33) 
at org.antlr.runtime.tree.TreeVisitor.visit(TreeVisitor.java:33) 
at org.antlr.runtime.tree.TreeVisitor.visit(TreeVisitor.java:33) 
at org.antlr.runtime.tree.TreeVisitor.visit(TreeVisitor.java:33) 
at org.antlr.runtime.tree.TreeRewriter.downup(TreeRewriter.java:95) 
at org.antlr.runtime.tree.TreeRewriter.downup(TreeRewriter.java:86) 
at org.antlr.v4.tool.GrammarTransformPipeline.reduceBlocksToSets(GrammarTransformPipeline.java:89) 
at org.antlr.v4.tool.GrammarTransformPipeline.process(GrammarTransformPipeline.java:78) 
at org.antlr.v4.Tool.process(Tool.java:360) 
at java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1080) 
at de.ustutt.sidewise.editor.generator.BnfModelGenerator.doGenerate(BnfModelGenerator.java:53) 
at org.eclipse.xtext.builder.BuilderParticipant.handleChangedContents(BuilderParticipant.java:524) 
at org.eclipse.xtext.builder.BuilderParticipant.handleChangedContents(BuilderParticipant.java:513) 
at org.eclipse.xtext.builder.BuilderParticipant.doGenerate(BuilderParticipant.java:498) 
at org.eclipse.xtext.builder.BuilderParticipant.doBuild(BuilderParticipant.java:263) 
at org.eclipse.xtext.builder.BuilderParticipant.build(BuilderParticipant.java:221) 
at org.eclipse.xtext.builder.impl.RegistryBuilderParticipant$DeferredBuilderParticipant.build(RegistryBuilderParticipant.java:161) 
at org.eclipse.xtext.builder.impl.RegistryBuilderParticipant.build(RegistryBuilderParticipant.java:69) 
at org.eclipse.xtext.builder.impl.XtextBuilder.doBuild(XtextBuilder.java:252) 
at org.eclipse.xtext.builder.impl.XtextBuilder.fullBuild(XtextBuilder.java:280) 
at org.eclipse.xtext.builder.impl.XtextBuilder.build(XtextBuilder.java:117) 
at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:734) 
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) 
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:205) 
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:245) 
at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:300) 
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) 
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:303) 
at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:359) 
at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:382) 
at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:144) 
at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:235) 
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55) 
+0

На самом деле, я бы предложил построить ваш Parser/Lexer в процессе сборки с помощью Maven или аналогичного инструмента построения –

+0

@SeanPatrickFloyd Спасибо за ваш комментарий, но это невозможно для меня. Я динамически генерирую файл .g4 и должен генерировать Lexer из этого файла. – Robin

+0

это все еще нормально. Либо вы создаете грамматику раньше на жизненном цикле, либо в отдельном проекте –

ответ

2

Это известная рабочая реализация:

private void compileGrammar(IResource resource, IProgressMonitor monitor) { 
    if (resource != null && resource instanceof IFile && (resource.getName().endsWith(".g4"))) { 
     IFile file = (IFile) resource; 

     try { 
      String outputDirectory = determineBuildFolder(file).toString(); 
      Log.info(this, "Building [file=" + file.getFullPath() + "]"); 
      Log.info(this, "Output to [dir= " + outputDirectory + "]"); 
      monitor.worked(1); 

      Tool tool = new Tool(new String[] { "-o", outputDirectory }); 
      tool.removeListeners(); 
      ErrorListener toolErrs = new ErrorListener(); 
      tool.addListener(toolErrs); 
      monitor.worked(1); 

      // Prep and process the grammar file 
      String loc = file.getLocation().toPortableString(); 
      Grammar g = tool.loadGrammar(loc); 
      tool.process(g, true); 
      monitor.worked(1); 

      if (toolErrs.hasErrors()) { 
       for (ANTLRMessage err : toolErrs.getErrList()) { 
        Log.error(this, err.toString()); 
        AntlrDTCore.getDefault().showConsoleMessage(err.toString(), AntlrDTCore.MSG_ERROR); 
       } 
      } 
      if (toolErrs.hasWarnings()) { 
       for (ANTLRMessage warn : toolErrs.getWarnList()) { 
        Log.warn(this, warn.toString()); 
        AntlrDTCore.getDefault().showConsoleMessage(warn.toString(), AntlrDTCore.MSG_WARNING); 
       } 
      } 

      postCompileCleanup(file, monitor); 
      monitor.worked(1); 
     } catch (Exception e) { 
      Log.error(this, "Build failed.", e); 
     } 
    } 
} 

Кстати, внешний вид например, вы используете XText - последний раз я проверил, что он использует модифицированную реализацию Antlr3.

+0

Спасибо за ваш комментарий. По сути, это тот же самый код, что и мой. Я нашел свой вопрос, он был связан с зависимостями, которые каким-то образом не были правильно решены. XText использует Antlr3, но не во время выполнения, но при запуске Worklfow и загружает его при первом запуске. Поэтому я не думаю, что полагаться на Antlr от Xtext в этом случае не является хорошей идеей. – Robin

Смежные вопросы