Code Monkey home page Code Monkey logo

inmemantlr's Introduction

inmemantlr

inmemantlr provides the functionality of ANTLR v4 through a simple API. Usually ANTLR requires the user to perform the grammar generation and compilation steps. Instead, inmemantlr does all of these steps automatically and in-memory while keeping all of the original ANTLR objects accessible through its GenericParser class which is serializable, and hence, can be reused at a later point in time or across different applications. inmemantlr can be used via an easy-to-use Java API or as command-line tool.

Moreover, you can easily generate a parse tree from a parsed file and convert it into various formats such as .dot, .xml or .json. A parse tree can be processed/translated by means of inmemantlr's ParseTreeProcessor class.

All of the above-mentioned inmemantlr features are illustrated by examples. inmemantlr is ready to use for all of the grammars-v4 grammars (for detailed examples please have a look at grammars-v4).

Status

Linux Build Status Test Coverage Maven Central

Authors and major contributors

TOC

Integration

API Usage Scenarios

Licence

Integration

Maven

inmemantlr is available on maven central and can be integrated by using the following dependency in the pom.xml file. Note, that the maven releases do not necessarily contain the newest changes that are available in the repository. The maven releases are kept in sync with the tagged releases. The API documentation for every release is avalable here. However, the content of this documentation, in particular the code examples and usage scenarios, is always aligned with the master branch of this repository. Hence, it might be that the latest inmemantlr features are not yet available through the maven package.

<dependency>
    <groupId>com.github.julianthome</groupId>
    <artifactId>inmemantlr-api</artifactId>
    <version>1.9.2</version>
</dependency>

API Usage Scenarios

The following code snippets shows an example how to use the API of inmemantlr; descriptions are provided as source code comments. For the sake of simplicity, exception handling is omitted for all of the following examples.

Get started

The code sample below shows how you could get started with inmemantlr. The class GenericParserToGo (available as of release 1.6) provides a very simple API that should be sufficient for most of the use cases: you only have to provide the ANTLR grammar file in conjunction with the file/string to parse, and a call to parse() (with the string and starting-rule as parameters) will return the corresponding parse tree.

File gfile = new File("Java.g4");
File cfile = new File("HelloWorld.java");
ParseTree pt = new GenericParserToGo(gfile).parse(cfile, "compilationUnit");

Simple parsing

// 1. load grammar
File f = new File("Java.g4");
GenericParser gp = new GenericParser(f);
// 2. load file content into string
String s = FileUtils.loadFileContent("HelloWorld.java");
// 3. set listener for checking parse tree elements. Here you could use any ParseTreeListener implementation. The default listener is used per default
gp.setListener(new DefaultListener());
// 4. compile Lexer and parser in-memory
gp.compile();
// 5. parse the string that represents the content of HelloWorld.java
ParserRuleContext ctx = gp.parse(s, "compilationUnit", GenericParser.CaseSensitiveType.NONE);

Parse tree generation

While providing access to the original ParseTree data-structure of ANTLR which can be obtained through the ParserRuleContext object, inmemantlr also provides it's own ParseTree data-structure and some ready-to-use utility classes which help with everyday tasks such as pruning, data-conversion, tree-traversal and translation.

If you would like to obtain the ParseTree from a parsed file, the following snippet could be of use:

File f = new File("Java.g4");
GenericParser gp = new GenericParser(f);
String s = FileUtils.loadFileContent("HelloWorld.java");

// this listener will create a parse tree from the java file
DefaultTreeListener dlist = new DefaultTreeListener();

gp.setListener(dlist);
gp.compile();

ParserRuleContext ctx = gp.parse(s, "compilationUnit", GenericParser.CaseSensitiveType.NONE);
// get access to the parse tree of inmemantlr
ParseTree pt = dlist.getParseTree();

Parse tree serialization

As depicted below, our ParseTree implementation can be serialized to various output formats such as .xml, .json or .dot.

String xml = parseTree.toXml();
String json = parseTree.toJson();
String dot = parseTree.toDot();

Serialization may be useful in case you would like to use parsing results across different applications or in case you would like get a quick and simple visualization of your parse tree by means of graphviz as in the example below.

Example Parse tree

Parse tree pruning

In case you are just interested in particular nodes of the parse tree, it is possible to pass a lambda expression as parameter to the DefaultTreeListener as illustrated in the example below. Only those nodes remain in the parse tree for which the lambda expression returns true.

private Set<String> filter  = new HashSet<>(Arrays.asList(new String []{
        "alternation", "expr", "literal",
}));
// ...
dlist = new DefaultTreeListener(s -> filter.contains(s));
// ...

Parse tree processing

With inmemantlr, you can easily process or translate a given Parse tree by means of an ParseTreeProcessor. Note, that ANTLR can automatically generate visitors/listeners from a given grammar which you can obtain through the GenericParser member function getAllCompiledObjects. However, in case you would like to develop a simple application inmemantlr ParseTreeProcessor might be sufficient for your use case.

The following example illustrates how to process a simple parse tree that represents a mathematical expression. Given the grammar definition below, parsing the string '3+100' would yield this parse tree:

ParseTree derived from simple expression '3+100'

grammar Ops;

Plus: '+';
Minus: '-';
Number: '-'?([0-9]|[1-9][0-9]+);

s: (expression)* EOF;
plus: Plus;
minus: Minus;
operation: plus | minus;
expression: operand operation operand;
operand: Number;

WS  :  [ \t\r\n]+ -> skip;

The following code example illustrates how to compute the result of a mathematical expression based on the above-mentioned grammar.

// ...
gp.compile();
// this example shows you how one could use inmemantlr for sequential parsing
ParseTree pt;
gp.parse("3+100");
pt = t.getParseTree();
// Process the Parse tree bottom-up starting from the leafs up to the root node
ParseTreeProcessor<String, String> processor = new ParseTreeProcessor<String, String>(pt) {
  @Override
  public String getResult() {
    // when all nodes have been processed, the result is available in the smap
    // value of the root node which is returned here
    return smap.get(pt.getRoot());
  }
  @Override
  protected void initialize() {
    // initialize smap - a data structure that keeps track of the intermediate
    // values for every node
    pt.getNodes().forEach(n -> smap.put(n, n.getLabel()));
  }
  // This operation is executed for each and every node in left to right and
  // bottom up order. Non-leaf nodes are processed only if all of their siblings
  // have been already processed
  @Override
  protected void process(ParseTreeNode n) {
    if(n.getRule().equals("expression")){
      int n0 = Integer.parseInt(smap.get(n.getChild(0)));
      int n1 = Integer.parseInt(smap.get(n.getChild(2)));
      int result = 0;
      switch(smap.get(n.getChild(1))) {
        case "+":
          result = n0 + n1;
        break;
        case "-":
          result = n0 - n1;
        break;
      }
      // store computation result of addition subtraction for current node
      smap.put(n, String.valueOf(result));
    } else {
      // when node is no expression NT, propate child node value 1:1
      // to parent
      simpleProp(n);
    }
  }
};
// compute the result
processor.process();
// print the computation results which is 103
System.out.println(processor.getResult());

A more practical example on how to use the Parse tree processor can be found within my CTrans project which takes a given boolean formula and translates it into CNF or DNF, respectively.

Sequential parsing

If you have multiple strings to parse one after another, the following code snippet might be useful:

File f = new File("Simple.g4");
GenericParser gp = new GenericParser(f);

// note that the listener should always be set before
// the compilation. Otherwise, the listener cannot
// capture the parsing information.
gp.setListener(new DefaultTreeListener());
gp.compile();

ParseTree pt;
gp.parse("PRINT a+b");
pt = t.getParseTree();
// do something with parsing result

gp.parse("PRINT \"test\"");
pt = t.getParseTree();
// do something with parsing result

Non-combined grammars

// define array of ANTLR files to consider -- inmemantlr will automatically
// analyses their interdependencies
File files [] = {
  new File("MySQLLexer.g4"),
  new File("MySQLParser.g4")
};
// simply pass files to constructor
GenericParser gp = new GenericParser(files);
// parser is ready to use

Lexer-only grammars

In case you are interested in only using a lexer grammar, you can use the lex method which will provide you with a list of tokens.

GenericParser gp = new GenericParser(new File("LexerGrammar"));
gp.compile();
try {
    List<Token> tokens = gp.lex("a09");
    Assertions.assertEquals(tokens.size(), 2);
} catch (IllegalWorkflowException e) {
    Assertions.assertFalse(true);
}

Accessing ANTLR objects

For accessing the ANTLR parser/lexer objects, you can use the getAllCompiledObjects method which will return the source and byte code of the source files that were generated by ANTLR and the corresponding byte code generated by inmenantlr.

// get access to ANTLR objects
MemoryTupleSet set = gp.getAllCompiledObjects();
// memory tuple contains the generated source code of ANTLR
// and the associated byte code
for(MemoryTuple tup : set) {
  // get source code object
  MemorySource = tup.getSource();
  // get byte code objects
  Set<MemoryByteCode> bcode = tup.getByteCodeObjects();
}

Through the method writeAntlrArtifactsTo, which belongs to the GenericParser class, inmemantlr also offers the possibility to write the ANTLR artifacts, i.e., the Java source files for a grammar/lexer, to a file.

// ...
GenericParser gp = new GenericParser(tc,sgrammarcontent);
// ...
gp.writeAntlrAritfactsTo("/tmp/grammar");

After the call above, you will find the .java files in the specified destination /tmp/grammar.

Parser serialization

For avoiding unnecessary compilation and for enabling the re-use of a generic parser across different Java applications or runs, it is possible to serialize a generic parser.

A generic parser could be serialized to a file with the following code:

// store a generic parser in the file "/tmp/gp.out" and
// overwrite the file if it already exists
gp.store("/tmp/gp.out", true);

A generic parser can be loaded from a file with the following code:

// load generic parser from file /tmp/gp.out
GenericParser gp = GenericParser.load("/tmp/gp.out");

grammars-v4

The grammars-v4 repository is added as a submodule. For executing all the grammars-v4 test cases, one could run the following commands from within the inmemantlr-api maven module.

git submodule init
git submodule update
mvn -Dtest=TestExternalGrammars test

Licence

The MIT License (MIT)

Copyright (c) 2016 Julian Thome [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

inmemantlr's People

Contributors

alankstewart avatar calogero75 avatar dafei1288 avatar dependabot[bot] avatar havrikov avatar julianthome avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

inmemantlr's Issues

How to use "Utility Files"

Dear Julian and Team,

first of all, thanks a lot for providing this project.
I have figured out, how to make use of the Utility files. See the example below.

Furthermore I would like to suggest to implement the TreeNode interface in order to make it easier to use the UI.
Please see the attached patch.

Cheers!

import java.awt.Dimension;
import java.io.File;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.snt.inmemantlr.GenericParser;
import org.snt.inmemantlr.exceptions.CompilationException;
import org.snt.inmemantlr.exceptions.IllegalWorkflowException;
import org.snt.inmemantlr.exceptions.ParsingException;
import org.snt.inmemantlr.listener.DefaultTreeListener;
import org.snt.inmemantlr.tree.ParseTree;

/**
 *
 * @author are
 */
public class TestSimple {

  private static final Logger LOGGER = LoggerFactory.getLogger(TestSimple.class);

  public static void main(String[] args) throws Exception {
    ClassLoader cl = TestSimple.class.getClassLoader();

    File lexerFile = new File(cl.getResource("com/manticore/g4/PlSqlLexer.g4").toURI());
    File parserFile = new File(cl.getResource("com/manticore/g4/PlSqlParser.g4").toURI());
    
    File abstractLexerClassFile = new File(FileUtils.getTempDirectory(), "PlSqlLexerBase.java");
    abstractLexerClassFile.deleteOnExit();
    
    File abstractParserClassFile = new File(FileUtils.getTempDirectory(), "PlSqlParserBase.java");
    abstractLexerClassFile.deleteOnExit();
    
    FileUtils.copyInputStreamToFile(cl.getResourceAsStream("com/manticore/g4/PlSqlLexerBase.java.txt"), abstractLexerClassFile);
    FileUtils.copyInputStreamToFile(cl.getResourceAsStream("com/manticore/g4/PlSqlParserBase.java.txt"), abstractParserClassFile);

    GenericParser gp = new GenericParser(lexerFile, parserFile);

    gp.addUtilityJavaFiles(abstractLexerClassFile, abstractParserClassFile);

    DefaultTreeListener t = new DefaultTreeListener();
    gp.setListener(t);

    boolean compile;
    try {
      gp.compile();
      compile = true;
      // gp.writeAntlrAritfactsTo("/tmp/grammar");
      // gp.store("/tmp/grammar/gp.out", true);
    } catch (CompilationException e) {
      LOGGER.error(e.getMessage(), e);
      compile = false;
    }

    // this example shows you how one could use inmemantlr for incremental parsing
    try {
      ParseTree parseTree;
      gp.parse("SELECT a, b, c from t1 inner join t2 on t1.a=t2.b;", GenericParser.CaseSensitiveType.UPPER);
      parseTree = t.getParseTree();

      JTree tree = new JTree(parseTree.getRoot());
      JScrollPane scrollPane = new JScrollPane(tree);
      JFrame frame = new JFrame("Simple SQL parser test");
      frame.add(scrollPane);
      frame.setPreferredSize(new Dimension(480, 640));
      frame.pack();
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

      frame.setVisible(true);

    } catch (IllegalWorkflowException | ParsingException e) {
      LOGGER.error(e.getMessage(), e);
    }
  }
}

ParseTreeNode.java.zip

I can not run all test case

My ENV:
IDEA 2016.2 (default junit4)
JDK 1.8

Question:
why use junit5 ? (org.junit.jupiter.api)
how to run these test case ? give me your develop env info.

class Version

Hi Julian,
when I use this tool, it displays as follows.
Error: (4, 26) java: Unable to access org.snt.inmemantlr.GenericParser
Wrong class file: /E:/maven/maven_rep1/com/github/julianthome/inmemantlr-api/1.7.0/inmemantlr-api-1.7.0.jar!/org/snt/inmemantlr/GenericParser.class
The class file has the wrong version 54.0, it should be 52.0
Please delete the file or make sure that the file is in the correct classpath subdirectory.

Can't load any v4 grammars

Sticking to your sample code in the readme, I can't get any of the grammars-v4 to work. When initializing GenericParser with java8.g4, for instance, it says:

error(50): :1448:3: syntax error: '1-9' came as a complete surprise to me while matching a lexer rule
error(50): :1469:7: syntax error: 'xX' came as a complete surprise to me while looking for lexer rule element
error(50): :1479:3: syntax error: '0-9a-fA-F' came as a complete surprise to me while matching a lexer rule
error(50): :1505:3: syntax error: '0-7' came as a complete surprise to me while matching a lexer rule
error(50): :1521:7: syntax error: 'bB' came as a complete surprise to me while looking for lexer rule element
error(50): :1531:3: syntax error: '01' came as a complete surprise to me while matching a lexer rule
error(50): :1567:3: syntax error: 'eE' came as a complete surprise to me while matching a lexer rule
error(50): :1577:3: syntax error: '+-' came as a complete surprise to me while matching a lexer rule
error(50): :1582:3: syntax error: 'fFdD' came as a complete surprise to me while matching a lexer rule
error(50): :1593:7: syntax error: 'xX' came as a complete surprise to me while looking for lexer rule element
error(50): :1603:3: syntax error: 'pP' came as a complete surprise to me while matching a lexer rule
error(50): :1622:4: syntax error: ''\\\r\n]\n\t;\n\n// §3.10.5 String Literals\n\nStringLiteral\n\t:\t'"' StringCharacters? '"'\n\t;\n\nfragment\nStringCharacters\n\t:\tStringCharacter+\n\t;\n\nfragment\nStringCharacter\n\t:\t~["\\\r\n]\n\t|\tEscapeSequence\n\t;\n\n// §3.10.6 Escape Sequences for Character and String Literals\n\nfragment\nEscapeSequence\n\t:\t'\\' [btnfr"'\\' came as a complete surprise to me while looking for lexer rule element
error(50): :1660:3: syntax error: '0-3' came as a complete surprise to me while matching a lexer rule
error(50): :1735:3: syntax error: 'a-zA-Z$_' came as a complete surprise to me while matching a lexer rule
error(50): :1737:3: syntax error: '\u0000-\u007F\uD800-\uDBFF' came as a complete surprise to me while looking for lexer rule element
error(50): :1740:2: syntax error: '\uD800-\uDBFF' came as a complete surprise to me while matching a lexer rule
error(50): :1746:3: syntax error: 'a-zA-Z0-9$_' came as a complete surprise to me while matching a lexer rule
error(50): :1748:3: syntax error: '\u0000-\u007F\uD800-\uDBFF' came as a complete surprise to me while looking for lexer rule element
error(50): :1751:2: syntax error: '\uD800-\uDBFF' came as a complete surprise to me while matching a lexer rule
error(50): :1766:7: syntax error: ' \t\r\n\u000C' came as a complete surprise to me while matching a lexer rule
error(50): :1774:14: syntax error: '\r\n' came as a complete surprise to me while looking for lexer rule element

The line producing the output above is simply:

this.parser = new GenericParser(grammarFile);

where grammarFile is the java8.g4 file.

Ignoring the messages above and going on with the following:

this.parser.setListener(new ParserListener());
this.parser.compile();

fails with this exception:

 org.snt.inmemantlr.exceptions.CompilationException: No string code pipeline availabe
	at org.snt.inmemantlr.GenericParser.compile(GenericParser.java:313)

Using version 1.4 of inmemantlr (for compatibility with Java 8). Any pointers are appreciated.

Can't parse with DE-serialized parser

Hi Julian,

everything works fine when creating a fresh Parser.
However, when I serialize the parser and de-serialize it (successfully without any error), the parse will fail:

Caused by: java.lang.NullPointerException
	at org.snt.inmemantlr.memobjects.MemoryByteCode.getBytes(MemoryByteCode.java:92)
	at org.snt.inmemantlr.comp.SpecialClassLoader.findClass(SpecialClassLoader.java:65)
	at org.snt.inmemantlr.comp.StringCompiler.findClass(StringCompiler.java:152)
	at org.snt.inmemantlr.comp.StringCompiler.instanciateLexer(StringCompiler.java:181)
	at org.snt.inmemantlr.GenericParser.parse(GenericParser.java:526)
	at org.snt.inmemantlr.GenericParser.parse(GenericParser.java:420)
	at com.manticore.jsqlformatter.JavaTools.formatJava(JavaTools.java:153)
	... 1 more

Shortened Java Code

    GenericParser gp =null;
    File cacheFolder = new File(System.getProperty( "java.io.tmpdir"));
    if (cacheFolder.exists() && cacheFolder.isDirectory()) {
      File cacheFile = new File(cacheFolder, "java_grammar.out");
      if (cacheFile.exists() && cacheFile.canRead()) {
        LOGGER.info("Found cache file " + cacheFile.getAbsolutePath());
        try {
          gp = GenericParser.load(cacheFile.getAbsolutePath());
        } catch (Exception ex) {
          LOGGER.log(Level.WARNING, "Failed to read the cached grammer from " + cacheFile.getAbsolutePath(), ex);
          cacheFile.delete();
        }
      }
    }

    gp.setListener(t);
    try {
      ParseTree parseTree;
      gp.parse(source.toString(), GenericParser.CaseSensitiveType.NONE);
      parseTree = t.getParseTree();
    } catch (Exception ex) {
      throw new Exception("Could not parse Java Code:\n" + javaCode, ex);
    }

Before I have serialized the Parser like shown below:

    if (gp==null) {
      LOGGER.info("Compile new Generic Parser.");
       
      gp = new GenericParser(lexerContent, parserContent);
      gp.compile();
      if (cacheFolder.exists() && cacheFolder.isDirectory()) {
        File cacheFile = new File(cacheFolder, "java_grammar.out");
        gp.store(cacheFile.getAbsolutePath(), true);
        
        LOGGER.info("Saved cache file " + cacheFile.getAbsolutePath());
      }
    }

The Parser is correct and works fine when I create it afresh.
But it fails with the NPE when loading it from the file.

I have the File java_grammar.out attached:
java_grammar.zip

Line and Column Error in ParseTreeNode

Class ParseTreeNode has methods getSidx() and getEidx(), but these methods are not sufficient.

There should also be methods getBeginLine(), getBeginCharPositionInLine(), genEndLine(), and getEndCharPositionInLine().

This way, we can quickly locate where the node is in the source parsed. Useful for output detailed error messages.

Release on maven central

Is there any reason for it to not to be released on maven central? This plugin is very relevant and useful.

How to get all the nodes after filtering

Dear Julian
Recently I applied filtering for CPP code to get only function body.. Can you please guide me how to generate all the descending nodes of function body.. I mean I m interested in getting all the nodes of function body till last level.. I tried calling getNodes() method from DefaultTreelistner class. But it is creating error as java.util.List cannot be converted to ParseTreeNode.. Kindly help

Problem 1.3 release and dynamically generating a class file

I'm getting this dump:


Exception in thread "main" java.lang.IllegalArgumentException: bytecode of class GenScalaFacadesFromTypescriptLexer is empty
at org.snt.inmemantlr.comp.SpecialJavaFileManager.getByteCodeFromClass(SpecialJavaFileManager.java:99)
at org.snt.inmemantlr.comp.StringCompiler.compile(StringCompiler.java:135)
at org.snt.inmemantlr.GenericParser.compile(GenericParser.java:293)
at com.cyberthinkers.tools.GenScala$.parseSource(GenScalaFacadesFromTypescriptBaseListenerScala.scala:36)
at com.cyberthinkers.tools.GenScala$.main(GenScalaFacadesFromTypescriptBaseListenerScala.scala:27)
at com.cyberthinkers.tools.GenScala.main(GenScalaFacadesFromTypescriptBaseListenerScala.scala)

I have a TypeScript ambient grammar that I wrote, and your library is crashing when your librar tries to compile it. It works correctly when I use the standard library.

Cleanup API

Make sure the parameter order is the same for all GenericParser functions.

Error when using with spring boot and antlr4

I am working a project to general runtime grammars for parse email and I am getting this when trying to parse my files:

153. ERROR in /PisosGrammarParser.java (at line 1724)
	_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
	                                                     ^^^^
ATN cannot be resolved to a type
----------
----------
154. ERROR in /PisosGrammarListener.java (at line 2)
	import org.antlr.v4.runtime.tree.ParseTreeListener;
        ^^^^^^^^^
The import org.antlr cannot be resolved

I generate a spring boot jar with spring boot maven plugin.

Do you have any idea about this issue?

Thanks!

Compiler Options

Additional compiler options to have more impact on grammar compilation

Source for lexer isn't being generated with V1.3.1

For some reason, the lexer isn't being generated in V1.3.1. Any ideas? Also, the Eclipse compiler isn't being brought in for some reason via your POM reference. So I had to add it to the build.
(See https://github.com/cyberthinkers/typescript-to-scala-js-facade - it's a work in progress.)

Exception in thread "main" java.lang.IllegalArgumentException: bytecode of class GenScalaFacadesFromTypescriptLexer is empty
at org.snt.inmemantlr.comp.SpecialJavaFileManager.getByteCodeFromClass(SpecialJavaFileManager.java:99)
at org.snt.inmemantlr.comp.StringCompiler.compile(StringCompiler.java:135)
at org.snt.inmemantlr.GenericParser.compile(GenericParser.java:293)
at com.cyberthinkers.tools.GenScala$.parseSource(GenScalaFacadesFromTypescriptBaseListenerScala.scala:35)
at com.cyberthinkers.tools.GenScala$.main(GenScalaFacadesFromTypescriptBaseListenerScala.scala:27)
at com.cyberthinkers.tools.GenScala.main(GenScalaFacadesFromTypescriptBaseListenerScala.scala)

Save parser

It would be nice to have a feature which allows one to save a GenericParser on disk after using its compile method so one does not have to compile a specific grammar every time the software starts. I tried ObjectOutputStream which was expected to fail at this task and it did. Do you have any suggestions?

Btw I am glad that you created this antlr wrapper putting a parse result into a real tree and provided a working graphviz output (unlike antlr4).

Don't know where or how to ask

I suppose inmemantlr doesn't support the C# grammar provided at: https://github.com/antlr/grammars-v4

Is there a possibility to get an AST using inmemantlr from parsers generated by ANTLR4?

Thanks, and sorry for opening an issue for this.

I tried to do this:

val file = Source.fromFile(src).mkString
val read = file //.getLines
val dtListener = new DefaultTreeListener()

val stream = new ANTLRInputStream(read)

val lexer = new CSharpLexer(stream)

val tokens = new CommonTokenStream(lexer)

val parser = new CSharpParser(tokens)

parser.addParseListener(dtListener)

val ast: Ast = dtListener.getAst

But doesn't seem to work.

Serialize grammar to project classpath

Would be great to have an option to serialize the ANTLR Java classes to the project classpath. This is useful for cases where the grammar is ready-to-use for production and no code-generation/compilation is required anymore.

InmemantlrTool uses only terminal-defined package names, ignoring action-defined ones

Hello.

InmemantlrTool here, while setting lexer/parser, gets a package name using this logic which includes only a terminal-based package name, as noted multiple times in antlr4 lib.

But if we set those packages using .g4 actions like in this example:

...
@header {
    package foo.bar;
}
...

GenericParser may throw an exception, for example, here, because SpecialClassLoader can't find a class with a name which doesn't includes packages. m may contain full class names here, but the method parameter name is only a class name without packages, because, as I said earlier, InmemantlrTool uses only terminal-defined packades.

We can workaround this by setting lexer or parser names (with packages) manually after a parser was compiled, but it doesn't seem like a good soltuion for me. But if it's intended and a good way to set up these names, it would be nice to have some notes in documentation or exceptions. Currently, this may lead to this exception: java.lang.NullPointerException: Cannot invoke "org.antlr.v4.runtime.Lexer.addErrorListener(org.antlr.v4.runtime.ANTLRErrorListener)" because "lex" is null which doesn't contain any hints about lexerName or parserName.

Improve output for dot format

Remove the output scheme where textfragments are displayed with inside the node. This is too error prone because the text may contain invalid characters depending on what input language you are parsing.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.