Frage

I did find an answer to my question: Barts answer is exactly why I need, but it does not function (see below).

Please can some one either give me a working example or show me the where I am going wrong to implement Barts answer?

This is what I get for the other answer, I get the hereunder error from "part 4"

Lexer lexer = (Lexer)Class.forName(grammarName + "Lexer").newInstance();

I've got antlr3.4 complete and JDK libraries. I created it as package createclass; yet I find the answer strange as the class to create has no package??? So I tried adding to the string:

"@lexer::header {\n" +
"   package createclass;\n" +
"}        \n" +
"@parser::header {\n" +
"   package createclass;\n" +
"}\n" +

But still no change.

Here's the output:

debug:
Exception in thread "main" java.lang.ClassNotFoundException: TLexer
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:169)
    at createclass.Createclass.main(Createclass.java:61)
Java Result: 1
BUILD SUCCESSFUL (total time: 31 seconds)

The example code given is:

import java.io.*;
import javax.tools.*;
import java.lang.reflect.*;
import org.antlr.runtime.*;
import org.antlr.Tool;

public class Main {

    public static void main(String[] args) throws Exception {

        // The grammar which echos the parsed characters to theconsole,
        // skipping any white space chars.
        final String grammar =
                "grammar T;                                                  \n" +
                "                                                            \n" +
                "parse                                                       \n" +
                "  :  (ANY {System.out.println(\"ANY=\" + $ANY.text);})* EOF \n" +
                "  ;                                                         \n" +
                "                                                            \n" +
                "SPACE                                                       \n" +
                "  :  (' ' | '\\t' | '\\r' | '\\n') {skip();}                \n" +
                "  ;                                                         \n" +
                "                                                            \n" +
                "ANY                                                         \n" +
                "  :  .                                                      \n" +
                "  ;                                                           ";
        final String grammarName = "T";
        final String entryPoint = "parse";

        // 1 - Write the `.g` grammar file to disk.
        Writer out = new BufferedWriter(new FileWriter(new File(grammarName + ".g")));
        out.write(grammar);
        out.close();

        // 2 - Generate the lexer and parser.
        Tool tool = new Tool(new String[]{grammarName + ".g"});
        tool.process();

        // 3 - Compile the lexer and parser.
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        compiler.run(null, System.out, System.err, "-sourcepath", "", grammarName + "Lexer.java");
        compiler.run(null, System.out, System.err, "-sourcepath", "", grammarName + "Parser.java");

        // 4 - Parse the command line parameter using the dynamically created lexer and 
        //     parser with a bit of reflection Voodoo :)
        Lexer lexer = (Lexer)Class.forName(grammarName + "Lexer").newInstance();
        lexer.setCharStream(new ANTLRStringStream(args[0]));
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        Class<?> parserClass = Class.forName(grammarName + "Parser");
        Constructor parserCTor = parserClass.getConstructor(TokenStream.class);
        Parser parser = (Parser)parserCTor.newInstance(tokens);
        Method entryPointMethod = parserClass.getMethod(entryPoint);
        entryPointMethod.invoke(parser);
    }
}
War es hilfreich?

Lösung

My guess is that you're using an IDE for this, and don't have your classpath set properly. The demo from my answer works (also using v3.4). Here's what I just did:

I copied the file Main.java in a directory (~/Temp/demo, in my case) and opened a shell in this directory and did the following:

bart@hades:~/Temp/demo$ java -version
> java version "1.6.0_24"
> OpenJDK Runtime Environment (IcedTea6 1.11.4) (6b24-1.11.4-1ubuntu0.12.04.1)
> OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)

bart@hades:~/Temp/demo$ wget http://www.antlr.org/download/antlr-3.4-complete.jar
> --2012-10-17 19:26:01--  http://www.antlr.org/download/antlr-3.4-complete.jar
> Resolving www.antlr.org (www.antlr.org)... 138.202.170.10
> Connecting to www.antlr.org (www.antlr.org)|138.202.170.10|:80... connected.
> HTTP request sent, awaiting response... 200 OK
> Length: 2388361 (2.3M) [application/java-archive]
> Saving to: `antlr-3.4-complete.jar'
> 
> 100%[===============================================================================================================>] 2,388,361    317K/s   in 8.9s    
> 
> Last-modified header invalid -- time-stamp ignored.
> 2012-10-17 19:26:11 (261 KB/s) - `antlr-3.4-complete.jar' saved [2388361/2388361]

bart@hades:~/Temp/demo$ javac -cp antlr-3.4-complete.jar *.java

bart@hades:~/Temp/demo$ java -cp .:antlr-3.4-complete.jar Main "a b    c"
> ANY=a
> ANY=b
> ANY=c

(the > is output printed to the console)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top