Git Product home page Git Product logo

javacc2antlr's Introduction

JavaCC2ANTLR

Build Status

JavaCC is an old and venerable tool, used in so many projects. In recent years however ANTLR seems to have a growing community and there are different tools to support ANTLR. Also, ANTLR can be used to generate a parser for so many target languages that are not supported by JavaCC.

So I hacked together this little project, in Kotlin.

For now it basically get a JavaCC grammar and produces a lexer and a parser ANTLR grammar which should hopefully be equivalent.

Generate ANTLR Lexer & Parser

Simply look at the class JavaCCToAntlrConverter. It takes the file name of the JavaCC grammar and outputs a Lexer and a parser Grammar.

Generate an ANTLR in memory

val file = File("src/test/resources/java.jj")
val grammarName = file.nameWithoutExtension.capitalize()

val javaCCGrammar = loadJavaCCGrammar(file)
val antlrGrammar = javaCCGrammar.convertToAntlr(grammarName)
this.genericParser = antlrGrammar.genericParser()
val ast = genericParser.parse("class A { }")

Push/Pop Mode Commands

JavaCC by default does not have a way for tokens to change the token manager lexical state with memory, like ANTLR provides with the pushMode and popMode commands. For example, to parse as a single token a balanced set of parentheses such as ((()) ()) you might have the following JavaCC parser:

TOKEN_MGR_DECLS : {
    static List<Integer> lexicalStateStack = new ArrayList<Integer>();

    static void openParen() {
        lexicalStateStack.add(curLexState);
    }

    static void closeParen() {
        SwitchTo(lexicalStateStack.remove(lexicalStateStack.size() - 1));
    }
}

<DEFAULT, LEVEL1, LEVELN> SKIP : {
    < " " >
}

<LEVELN> MORE : {
    <LPAREN:    "("> { openParen(); }
|   <RPAREN:    ")"> { closeParen(); }
}

MORE : {
    < "(" > { openParen(); } : LEVEL1
}

<LEVEL1> MORE : {
    < "(" > { openParen(); } : LEVELN
}

<LEVEL1> TOKEN : {
    <BALANCED_PARENS: ")" > { closeParen(); } : DEFAULT
}

void Start(): {} { <BALANCED_PARENS> <EOF> }

However, the ANTLR lexer would not behave correctly because we cannot infer when, according to the SwitchTo statements executed as part of the actions, the corresponding ANTLR rules should use mode, pushMode, or popMode commands:

lexer grammar Lexer;

SKIP0 : ' ' -> skip ;
MORE0 : '(' -> more, mode(LEVEL1) ;

mode LEVEL1;
LEVEL1_SKIP0 : SKIP0 -> skip ;
MORE1 : '(' -> more, mode(LEVELN) ;
BALANCED_PARENS : ')' -> mode(DEFAULT_MODE) ;

mode LEVELN;
LEVELN_SKIP0 : SKIP0 -> skip ;
LPAREN : '(' -> more ;
RPAREN : ')' -> more ;  // PROBLEM: Cannot escape this mode!


parser grammar Parser;

options { tokenVocab=Lexer; }

start :  BALANCED_PARENS EOF  ;

In order to handle such actions, you must add the following fields to your TOKEN_MGR_DECLS with values set to the name of your functions that should map to pushMode and popMode commands respectively:

TOKEN_MGR_DECLS : {
    ...
    final static String pushStateFunc = "openParen";
    final static String popStateFunc = "closeParen";
}

Now the lexer gets generated correctly:

SKIP0 : ' ' -> skip ;
MORE0 : '(' -> more, pushMode(LEVEL1) ;

mode LEVEL1;
LEVEL1_SKIP0 : SKIP0 -> skip ;
MORE1 : '(' -> more, pushMode(LEVELN) ;
BALANCED_PARENS : ')' -> popMode ;

mode LEVELN;
LEVELN_SKIP0 : SKIP0 -> skip ;
LPAREN : '(' -> more, pushMode(LEVELN) ;
RPAREN : ')' -> more, popMode ;

Licensing

The project is made available under the Apache Public License V2.0. Please see the file called LICENSE.

javacc2antlr's People

Contributors

br0nstein avatar ftomassetti avatar fujin avatar gunnarmorling avatar matozoid avatar

Stargazers

 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

javacc2antlr's Issues

TestCase Failed

hello,there some error in the convert, can you help?

-junit4 com.strumenta.javacc.JavaGrammarTest
Parsing src\test\resources\guava-src\com\google\common\annotations\Beta.java
Parsing src\test\resources\guava-src\com\google\common\annotations\GwtCompatible.java
Parsing src\test\resources\guava-src\com\google\common\annotations\GwtIncompatible.java
Parsing src\test\resources\guava-src\com\google\common\annotations\package-info.java
Parsing src\test\resources\guava-src\com\google\common\annotations\VisibleForTesting.java
Parsing src\test\resources\guava-src\com\google\common\base\Absent.java
Parsing src\test\resources\guava-src\com\google\common\base\AbstractIterator.java
Parsing src\test\resources\guava-src\com\google\common\base\Ascii.java

org.snt.inmemantlr.exceptions.ParsingException: (line 630,char 34): mismatched input '')' expecting {'instanceof', ')', '[', '.', '=', '<', '?', '==', '<=', '>=', '!=', '||', '&&', '++', '--', '+', '-', '', '/', '&', '|', '^', '%', '<<', '+=', '-=', '=', '/=', '&=', '|=', '^=', '%=', '<<=', '>>=', '>>>=', '->', '::', '>'}

at org.snt.inmemantlr.GenericParser.parse(GenericParser.java:544)
at org.snt.inmemantlr.GenericParser.parse(GenericParser.java:391)
at org.snt.inmemantlr.GenericParser.parse(GenericParser.java:354)
at com.strumenta.javacc.JavaGrammarTest.parseJavaFile(JavaConversion.kt:130)
at com.strumenta.javacc.JavaGrammarTest.parseDir(JavaConversion.kt:123)
at com.strumenta.javacc.JavaGrammarTest.parseDir(JavaConversion.kt:121)
at com.strumenta.javacc.JavaGrammarTest.parseDir(JavaConversion.kt:121)
at com.strumenta.javacc.JavaGrammarTest.parseDir(JavaConversion.kt:121)
at com.strumenta.javacc.JavaGrammarTest.parseDir(JavaConversion.kt:121)
at com.strumenta.javacc.JavaGrammarTest.canParseAllGuava(JavaConversion.kt:115)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Process finished with exit code -1

Open Source License

Greetings,

I am wondering if you can make this code available under an open source license.

Thanks for any insight!

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.