4
grammar Test;

IDHEAD: ('a'..'z' | 'A'..'Z' | '_');
IDTAIL: (IDHEAD | '0'..'9');
ID:     (IDHEAD IDTAIL*);
fragment
TYPE:   ('text' | 'number' | 'bool');

define: 'define' ID 'as' TYPE;

問題は、defineルールがトークン、、と一致しdefineますが、ID一致しないことです。MissingTokenExceptionが発生しています。asTYPE

次のようにTYPEをインライン化すると、意図したとおりに機能します。

grammar Test;

IDHEAD: ('a'..'z' | 'A'..'Z' | '_');
IDTAIL: (IDHEAD | '0'..'9');
ID:     (IDHEAD IDTAIL*);
fragment
TYPE:   ('text' | 'number' | 'bool');

define: 'define' ID 'as' ('text' | 'number' | 'bool');

更新:fragment別の競合を解決するために、キーワードが追加されました:The following token definitions can never be matched because prior tokens match the same input: TYPE

4

4 に答える 4

4

結合された文法では、パーサールールをレクサールールの上に配置します。また、レクサーが最初に実行され、パーサーが実行された後にのみ実行されることを忘れないでください。(レクサー)トークンが必要であることがわかる前に、TYPE(レクサー)トークンが一致しているdefine必要があります。

フラグメントレクサールールはトークンを作成しませんが、トークンを作成する非フラグメントルールに構成できます。あなたの例ではIDHEADIDTAILはトークンではありません-それらは単にの部分を説明するために使用されIDます。そのため、TYPEおよびIDは非フラグメントルールであり、IDHEADおよびIDTAILはフラグメントルールです。

grammar Test;

define: 'define' ID 'as' TYPE;

/*
 * Lexer rules only below here
 */

TYPE:   ('text' | 'number' | 'bool');
ID:     (IDHEAD IDTAIL*);

fragment
IDHEAD: ('a'..'z' | 'A'..'Z' | '_');

fragment
IDTAIL: (IDHEAD | '0'..'9');
于 2009-11-12T03:51:30.643 に答える
1

レクサールールは、それらがどのようにリストされるかを優先すると思いました。したがって、トークンTYPEを実際に作成する場合は、それを他のすべてのレクサールールの上に移動します。

grammar Test;

fragment
TYPE:   ('text' | 'number' | 'bool');
IDHEAD: ('a'..'z' | 'A'..'Z' | '_');
IDTAIL: (IDHEAD | '0'..'9');
ID:     (IDHEAD IDTAIL*);

define: 'define' ID 'as' TYPE;
于 2009-11-12T03:41:53.300 に答える
0

TYPEがフラグメントとして定義されているからではないですか?

現在テストできませんが、フラグメントを削除してみてください。これでうまくいくはずです。さらに、起動するためのトークンが提供されます。

于 2009-11-07T22:00:21.107 に答える
0

何をしているfragmentはずなのか?削除すれば期待通りに動作するはずです。

于 2009-11-07T22:58:39.257 に答える