私は今ANTLRを学んでいます。たとえば、VHDLコードがあり、PROCESSブロックでいくつかの処理を実行したいとします。残りは完全に無視する必要があります。プロセスブロックのみに関心があるので、VHDL言語全体を説明したくありません。したがって、プロセスブロックに一致するルールを作成できます。しかし、ANTLRにプロセスブロックルールのみに一致し、他のものを無視するように指示するにはどうすればよいですか?
2 に答える
私はVHDLがほとんどないことを知っているので、(Java)ソースファイル内のすべての単一行コメントを複数行コメントに置き換えたいとしましょう。
//foo
次のようになります。
/* foo */
もちろん、レクサーを1行のコメントと一致させる必要があります。//bar
ただし、次の場合に1行コメントとして認識されたくないため、複数行コメントを認識していることも確認する必要があります。
/*
//bar
*/
同じことが文字列リテラルにも当てはまります。
String s = "no // comment";
最後に、任意の文字に一致するある種のキャッチオールルールをレクサーに作成する必要があります。
簡単なデモ:
grammar T;
parse
: (t=. {System.out.print($t.text);})* EOF
;
Str
: '"' ('\\' . | ~('\\' | '"'))* '"'
;
MLComment
: '/*' .* '*/'
;
SLComment
: '//' ~('\r' | '\n')*
{
setText("/* " + getText().substring(2) + " */");
}
;
Any
: . // fall through rule, matches any character
;
ここで、次のように入力を解析する場合:
//comment 1
class Foo {
//comment 2
/*
* not // a comment
*/
String s = "not // a // comment"; //comment 3
}
以下がコンソールに出力されます。
/* comment 1 */
class Foo {
/* comment 2 */
/*
* not // a comment
*/
String s = "not // a // comment"; /* comment 3 */
}
これは単なる簡単なデモであることに注意してください。Javaの文字列リテラルにはUnicodeエスケープが含まれている可能性がありますが、これは私のデモではサポートされていません。また、私のデモではcharリテラルも処理されません(charリテラルchar c = '"';
はそれを壊します)。もちろん、これらはすべて簡単に修正できます。
今後のANTLRv4では、ファジー解析を実行できます。を見てみましょう
http://www.antlr.org/wiki/display/ANTLR4/Wildcard+Operator+and+Nongreedy+Subrules
ベータ版ソフトウェアはこちらから入手できます。
http://antlr.org/download/antlr-4.0b3-complete.jar
テレンス