2017-01-19 8 views
1

私はGRUNで、いくつかの文法をテストしていると私はトークンとして認識され、私のトークンを見ていませんよ。私は当初、このStackOverflow linkに基づいて「暗黙の」トークンを作成したと考えました。ANTLR4 grun rigはトークンを正しく報告していないようです...これはわかりますか?

また、grun -tokensの出力を確認すると、次のリンクが見つかりました: 1)最近のChangeの出力が-tokensです。 2)おそらく古いtestrig.md私はこれをフォークしましたし、その中に掘っています。ここで

は、私がこれを探求私の簡単なHelloTC.g4です:

grammar HelloTC; 
r : HELLO id; 
WS : [ \r\t\n]+ -> skip ; 
CMD: '%'; 
DIR: '%%'; 
A: 'A'; 
AA: 'AA'; 
HELLO:'hello'; 
ID : [a-z]+ ; 
id : DIR | CMD | A | AA; 

私はこれをテスト:

grun HelloTC r -tokens 
hello %% 
hello % 
hello A 
hello AA 
^Z 

[@0,0:4='hello',<'hello'>,1:0] 
[@1,6:7='%%',<'%%'>,1:6] 
[@2,10:14='hello',<'hello'>,2:0] 
[@3,16:16='%',<'%'>,2:6] 
[@4,19:23='hello',<'hello'>,3:0] 
[@5,25:25='A',<'A'>,3:6] 
[@6,28:32='hello',<'hello'>,4:0] 
[@7,34:35='AA',<'AA'>,4:6] 
[@8,38:37='<EOF>',<EOF>,5:0] 

私のトークンのいずれもトークンとして認識されていません。 私は期待していた:私の期待通りの結果で

[@0,0:4='hello',<HELLO>,1:0] 
[@1,6:7='%%',<DIR>,1:6] 
[@2,10:14='hello',<HELLO>,2:0] 
[@3,16:16='%',<CMD>,2:6] 
[@4,19:23='hello',<HELLO>,3:0] 
[@5,25:25='A',<A>,3:6] 
[@6,28:32='hello',<HELLO>,4:0] 
[@7,34:35='AA',<AA>,4:6] 
[@8,38:37='<EOF>',<EOF>,5:0] 

を私はトークン名と「は文字」を置き換えます。

私はちょうど何GRUNログレポートを誤って理解していれば今、私は思ったんだけど、-Xlogでantlr4走り、私のトークンは、(第2最後の行に)宣言されています。私は<のデータがレクサーによって渡されたTOKENの名前であると予想しました。私はそれを間違っていますか?

私はトークンをトークンとして認識されるように得るために、私の文法に何ができますか? OR ...レクサーがトークンを正しく識別していることを確認するために、どのように文法をデバッグするのですか?

2017-01-20 06:57:29:640 grammar LogManager.java:25 before: (COMBINED_GRAMMAR HelloTC (RULES (RULE r (BLOCK (ALT HELLO id))) (RULE WS (BLOCK (LEXER_ALT_ACTION (ALT (+ (BLOCK (ALT [ \r\t\n])))) skip))) (RULE CMD (BLOCK (ALT '%cat'))) (RULE DIR (BLOCK (ALT '%%'))) (RULE A (BLOCK (ALT 'A'))) (RULE AA (BLOCK (ALT 'AA'))) (RULE HELLO (BLOCK (ALT 'hello'))) (RULE id (BLOCK (ALT DIR) (ALT CMD) (ALT A) (ALT AA))))) 
2017-01-20 06:57:29:661 grammar LogManager.java:25 after: (COMBINED_GRAMMAR HelloTC (RULES (RULE r (BLOCK (ALT HELLO id))) (RULE WS (BLOCK (LEXER_ALT_ACTION (ALT (+ (BLOCK (ALT [ \r\t\n])))) skip))) (RULE CMD (BLOCK (ALT '%cat'))) (RULE DIR (BLOCK (ALT '%%'))) (RULE A (BLOCK (ALT 'A'))) (RULE AA (BLOCK (ALT 'AA'))) (RULE HELLO (BLOCK (ALT 'hello'))) (RULE id (BLOCK (ALT (SET DIR CMD A AA)))))) 
2017-01-20 06:57:29:694 grammar LogManager.java:25 after extract implicit lexer =(COMBINED_GRAMMAR HelloTC (RULES (RULE r (BLOCK (ALT HELLO id))) (RULE id (BLOCK (ALT (SET DIR CMD A AA)))))) 
2017-01-20 06:57:29:694 grammar LogManager.java:25 lexer =(LEXER_GRAMMAR HelloTCLexer (RULES (RULE WS (BLOCK (LEXER_ALT_ACTION (ALT (+ (BLOCK (ALT [ \r\t\n])))) skip))) (RULE CMD (BLOCK (ALT '%cat'))) (RULE DIR (BLOCK (ALT '%%'))) (RULE A (BLOCK (ALT 'A'))) (RULE AA (BLOCK (ALT 'AA'))) (RULE HELLO (BLOCK (ALT 'hello'))))) 
2017-01-20 06:57:30:040 semantics LogManager.java:25 tokens={EOF=-1, WS=1, CMD=2, DIR=3, A=4, AA=5, HELLO=6} 
2017-01-20 06:57:30:040 semantics LogManager.java:25 strings={'%cat'=2, '%%'=3, 'A'=4, 'AA'=5, 'hello'=6} 

私は文法を作成しようとしている構文のタイプの例は以下の通りです:

は、ここに私の-Xlogファイルです。

//COMMENTS 
;comments 
%%DIRECTIVEA 
%%DIRECTIVEB 
RESERVED_TOKEN(ARGS,ARGS) 
%commandA 
commandB 
commandD 
commandE 
... 
CommandH (only A-H allowed) 
// comments 
%commandB 
%%DIRECTIVEB 
%commandD 
commandE 
%commandA 
done 

私はまだ実験を行っています。うまくいけば、この質問、および任意の答えは他の人に役立つでしょう。

答えて

1

私も驚いています。以前のリリースでは、トークンの名前であっても翻訳されていなかった。

[@0,0:4='hello',<6>,1:0] 
[@1,6:7='%%',<3>,1:6] 
[@2,9:13='hello',<6>,2:0] 
[@3,15:15='%',<2>,2:6] 
[@4,17:21='hello',<6>,3:0] 
[@5,23:23='A',<4>,3:6] 
[@6,25:29='hello',<6>,4:0] 
[@7,31:32='AA',<5>,4:6] 
[@8,34:33='<EOF>',<-1>,5:0] 

年前、私は<grammar>.tokensファイルをフェッチすることによって、その名前に<n>を変換するRubyスクリプトを書いていました。 4.6で完了しました。

あなたは、HELLOを定義し、IDをこのようにして、この順序でいる場合:この入力と

HELLO 
    : [a-z]+ {getText().equals("hello")}? ; 
ID : [a-z]+ ; 

hello %% 
... 
    hello xyz 

あなたはこの結果を持っている:

[@0,0:4='hello',<HELLO>,1:0] 
    [@1,6:7='%%',<'%%'>,1:6] 
... 
    [@8,34:38='hello',<HELLO>,5:0] 
    [@9,40:42='xyz',<ID>,5:6] 

入力helloです2つのルールで一致させることができます。レクサー規則の構文述語は、入力がhelloであるときにレクサーがHELLOを選択することを可能にする。

定数はトークン名で表され、それ以外の入力はトークン名で表されます。この好奇心にもかかわらず、あなたのトークンは正しく認識されます。それがそうでないならば、パーサは文句を言うでしょう: 入力hello %% 123が与える:

$ grun Question r -tokens data.txt 
line 1:9 token recognition error at: '1' 
line 1:10 token recognition error at: '2' 
line 1:11 token recognition error at: '3' 
[@0,0:4='hello',<HELLO>,1:0] 
[@1,6:7='%%',<'%%'>,1:6] 

あなたは文法でINTルールを追加した場合

INT : [0-9]+ ; 

は、新しいトークンが認識されている:

[@0,0:4='hello',<HELLO>,1:0] 
[@1,6:7='%%',<'%%'>,1:6] 
[@2,9:11='123',<INT>,1:9] 
+0

追加のテストの後で、私が定義した文法/レクサーが機能していることを私は確信できました。私は、TOKEN_NAMEの試験注釈がANTLRの新しい機能であったことに気付きました。 –

0

これは完璧ではありません。 grun出力はまだトークンを出力しません。しかし、私は、System.out.printlin()アクションを挿入することで、Javaのターゲットを学ぶことができます。 欠点は、私が終わった後で、これらのデバッグ節を引き出す必要があることです。 最終的に私のターゲットパーサーはPythonベースになります。しかし、私はまだJavaの学習曲線上にあります。

このlinkは、デバッグにアクションを使用する方法を示しています。それと

、私は私のHelloTC.grをmodifed:

grammar HelloTC; 
r : HELLO id+ {System.out.println("r rule encountered");}; 
WS : [ \r\t\n]+ -> skip ; 
CMD: '%' {System.out.println("Lexer found a CMD");}; 
DIR: '%%'{System.out.println("Lexer found a DIR");}; 
A: 'A'; 
AA: 'AA'; 
HELLO:'hello'{System.out.println("Lexer found a HELLO");}; 
ID : [a-z]+ ; 
id : DIR | CMD | A | AA { System.out.println("Parser found rule match "+$text);}; 

そしてGRUN利回りでそれをデバッグ:

java org.antlr.v4.gui.TestRig HelloTC r -tokens 
hello%% 
hello %% 
^Z 
Lexer found a HELLO 
Lexer found a DIR 
Lexer found a HELLO 
Lexer found a DIR 
[@0,0:4='hello',<'hello'>,1:0] 
[@1,5:6='%%',<'%%'>,1:5] 
[@2,9:13='hello',<'hello'>,2:0] 
[@3,15:16='%%',<'%%'>,2:6] 
[@4,19:18='<EOF>',<EOF>,3:0] 
line 2:0 extraneous input 'hello' expecting {<EOF>, '%', '%%', 'A', 'AA'} 
r rule encountered 

だから、良いニュースは、レクサールールが見られているということで、私は分析/デバッグのための技術を持っています。私は滑りやすい斜面であるANTLRする修正「/テストを構築」したいのthatleads ...私はより多くの情報源を検討する必要がありますより多くの/解読GRUNを理解することだと思います。私は私の元の仕事に焦点を当てようとしています... パーサーを開発しています。

関連する問題