はほとんど何をしたいん文法である:
grammar PrintLang;
sentence
: statement
;
statement
: functionCall '(' argument ')' ';'
{
if ($functionCall.funName.equals("printf")) {
System.out.println($argument.arg);
}
}
;
functionCall returns [String funName]
: ID
{ $funName = $ID.text; }
;
argument returns [String arg]
: STRING
{ $arg = $STRING.text; }
;
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
WS : (' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
STRING
: '"' (ESC_SEQ | ~('\\'|'"'))* '"'
;
fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;
fragment
ESC_SEQ
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
| UNICODE_ESC
| OCTAL_ESC
;
fragment
OCTAL_ESC
: '\\' ('0'..'3') ('0'..'7') ('0'..'7')
| '\\' ('0'..'7') ('0'..'7')
| '\\' ('0'..'7')
;
fragment
UNICODE_ESC
: '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
;
私はAntlrWorksでこれを生成しました。すべてのトークンルールが私のために生成されました。
これはテストするためのJavaファイルです。
import org.antlr.runtime.*;
public class PrintIt {
public static void main(String args[]) {
String inputString = "printf(\"HelloWorld\");";
// Create an input character stream from standard in
ANTLRStringStream input = new ANTLRStringStream(inputString);
// Create an ExprLexer that feeds from that stream
PrintLangLexer lexer = new PrintLangLexer(input);
// Create a stream of tokens fed by the lexer
CommonTokenStream tokens = new CommonTokenStream(lexer);
// Create a parser that feeds off the token stream
PrintLangParser plParser = new PrintLangParser(tokens);
try {
plParser.sentence();
} catch (Exception e) {
e.printStackTrace();
}
}
}
あなたは私が、私もコメントがスタンダードを指し理由である、コメントを変更するとは考えていない(このJavaコードは、ANTLRのウェブサイトの例から、ほぼそのままのコピー/ペーストであることに注意しますが、コードは実際にStringを使用します)。そして、私がこれまでやっていたコマンドラインがあります。
bash$ java -cp ./antlr-3.4-complete.jar org.antlr.Tool PrintLang.g
bash$ javac -cp ./:./antlr-3.4-complete.jar PrintIt.java
bash$ java -cp antlr-3.4-complete.jar:. PrintIt
"HelloWorld"
おっと、私は私が印刷したい文字列がマッチしたトークン(引用符を含む「HelloWorldの」、)ではないことを忘れて、それが引用符内の文字列です。
また、printfの参照を文字列比較としてハードコーディングしていることにも気付くでしょう。実際には、特定のスコープでアクセス可能なシンボルを含む環境が必要になります(関連するantlrの "scope"構造を参照してください)。
最も重要なこと:Bart Kiersの答えは、より多くの質問に対してSOを検索することで見つかります。彼は優れたの例を掲載しています。
入力の文法は何ですか?あなたの入力はすべて1つのトークンですか?もしそうなら、簡単!あなたがCのようにそれを解析したいのであれば、それは "シンプル"から遠いです。 –
レコードの場合、C++は正しく解析するのが非常に難しいです。文脈依存です。 –
あなたはあなたの出力に言及します...あなたはコンパイラではなくインタープリタを書いていますか? –