2012-10-17 127 views
2

我的確找到了我的問題的答案:Barts answer正是我需要的原因,但它不起作用(見下文)。如何在運行時(運行時)生成詞法分析器和分析器?

請有人能給我一個工作的例子,或告訴我我要去哪裏實施Barts answer

這是我得到對方的回答,我是從「第4部分」

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

我有antlr3.4完整JDK庫得到了下面的錯誤。我創建它爲package createclass;但我發現答案奇怪,因爲創建的類沒有包? 所以我嘗試添加到字符串:

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

但仍然沒有改變。

下面是輸出:

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) 

給出的示例代碼:

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); 
    } 
} 

回答

2

我的猜測是,您使用的是這樣的一個IDE,並沒有你的類路徑設置正確。我的答案演示(也使用v3.4)。這裏就是我剛剛做:

我複製的文件Main.java在一個目錄(~/Temp/demo,在我的情況),並在該目錄中打開一個殼,也做了以下內容:

[email protected]:~/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) 

[email protected]:~/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] 

[email protected]:~/Temp/demo$ javac -cp antlr-3.4-complete.jar *.java 

[email protected]:~/Temp/demo$ java -cp .:antlr-3.4-complete.jar Main "a b c" 
> ANY=a 
> ANY=b 
> ANY=c

(該>輸出打印到控制檯)

+0

是,終於有人classpath中,只需要包括新的類()的文件夾中的當前文件夾 '的javac -cp。\ ANTLR-3.4-complete.jar *。 java' 'java -cp。;。\ antlr-3.4-complete.jar主「a b c」 然後在Netbeans中將其添加到:項目屬性>庫>運行>添加文件夾 謝謝 – xchiltonx