ANTLR
レクサーのルールはv4で
サーチ…
単純なルール
レクサールールはトークンタイプを定義します。彼らの名前は大文字で始まり、パーザのルールと区別する必要があります。
INTEGER: [0-9]+;
IDENTIFIER: [a-zA-Z_] [a-zA-Z_0-9]*;
OPEN_PAREN: '(';
CLOSE_PAREN: ')';
基本的な構文:
| 構文 | 意味 |
|---|---|
A | レクサールールまたはフラグメントA一致A |
AB | マッチA続いてB |
(A|B) | AまたはBいずれかに一致する |
'text' | リテラルの"text" |
A? | 一致0回または1回A |
A* | 0回以上マッチA |
A+ | 1回以上マッチA |
[A-Z0-9] | 定義された範囲(この例ではAZまたは0-9の間)で1文字を照合します。 |
'a'..'z' | 文字範囲の代替構文 |
~[AZ] | 範囲の否定- ない範囲で任意の一文字にマッチ |
. | 任意の1文字に一致する |
断片
フラグメントは、それ自体では一致しないレクサールールの再利用可能な部分です。レクサールールから参照する必要があります。
INTEGER: DIGIT+
| '0' [Xx] HEX_DIGIT+
;
fragment DIGIT: [0-9];
fragment HEX_DIGIT: [0-9A-Fa-f];
暗黙のレクサールール
以下のようなトークンをすると'{' パーサールールで使用されている明示的なルールが存在しない限り、暗黙のレクサーのルールは、彼らのために作成されます。
言い換えれば、レクサールールがある場合:
OPEN_BRACE: '{';
次に、これらのパーサー・ルールはどちらも同等です。
parserRule: '{';
parserRule: OPEN_BRACE;
しかし、 OPEN_BRACEレクサールールが定義されていない場合、暗黙的な匿名ルールが作成されます。その場合、暗黙のルールは、他のルールの前に定義されているかのように定義されます。つまり、他のルールよりも優先順位が高くなります。
優先ルール
複数のレクサールールが同じ入力テキストに一致することがあります。その場合、トークンタイプは次のように選択されます。
- まず、 最も長い入力に一致するレクサールールを選択します
- テキストが暗黙的に定義されたトークン(
'{')と一致する場合は、暗黙のルール - 複数のレクサールールが同じ入力長と一致する場合は、定義順に基づいて最初のレクサールールを選択します
以下の結合された文法:
grammar LexerPriorityRulesExample;
// Parser rules
randomParserRule: 'foo'; // Implicitly declared token type
// Lexer rules
BAR: 'bar';
IDENTIFIER: [A-Za-z]+;
BAZ: 'baz';
WS: [ \t\r\n]+ -> skip;
与えられた入力:
aaa foo bar baz barz
レクサーから次のトークンシーケンスが生成されます:
IDENTIFIER 'foo' BAR IDENTIFIER IDENTIFIER
aaaはIDENTIFIER型ですIDENTIFIERルールのみがこのトークンに一致することができます。あいまいさはありません。
fooの型は'foo'パーサールール
randomParserRuleは、IDENTIFIERルールよりも優先順位の高い暗黙的な'foo'トークンタイプを導入します。
barはBAR型ですこのテキストは、
IDENTIFIERルールの前に定義されているBARルールと一致するため、優先順位があります。
bazはIDENTIFIER型ですこのテキストは
BAZルールと一致しますが、IDENTIFIERルールにも一致します。後者は、BAR前に定義されているとおりに選択されます。文法が与えられると、
BAZは一致することができません。つまり、IDENTIFIERルールはすでにBAZが一致させることができるすべてをカバーします。
barzはIDENTIFIER型ですBARルールは、このストリング(bar)の最初の3文字と一致することができbarが、IDENTIFIERルールは4文字と一致します。IDENTIFIERは長い部分文字列と一致するため、BARよりもBARます。
経験則として、より一般的なルールの前に特定のルールを定義する必要があります。すでに定義済みのルールで既にカバーされている入力とルールが一致する場合のみ、そのルールは使用されません。
暗黙的に定義された'foo'などのルールは、他のすべてのレクサールールの前に定義されているかのように動作します。
レクサーコマンド
レクサールールには、関連するコマンドを含めることができます 。
WHITESPACE: [ \r\n] -> skip;
コマンドは、ルールの最後に->後に定義されます。
-
skip:一致するテキストをスキップします。トークンはエミットされません -
channel(n):別のチャンネルにトークンを送信する -
type(n):発行されたトークンのタイプを変更する -
mode(n)、pushMode(n)、popMode、more:レクサーモードを制御する
アクションとセマンティク述語
レクサーアクションは、 { ... }で囲まれたターゲット言語の任意のコードのブロックであり、マッチング中に実行されます。
IDENTIFIER: [A-Z]+ { log("matched rule"); };
セマンティック述語は、 { ... }?囲まれたターゲット言語の任意のコードブロック}?これはブール値に評価されます。戻り値がfalseの場合、レクサールールはスキップされます。
IDENTIFIER: [A-Z]+ { identifierIsValid() }?;
セマンティク述語は、パフォーマンス上の理由から可能な限り規則の最後に定義する必要があります。