0

私は古い言語の文法を開発しています。

言語はかなり複雑ですが、特定の問題に焦点を当てたいので、軽量バージョンを作成しました。軽量バージョンでは、割り当てステートメントと、数学演算や文字列連結などの単純な式を指定できます。

このような:

@assign[@var1 (1+3)*2]
@assign[@var2 "foo" $ "bar"]    

注:代入ステートメント内では、変数は @ 文字で始まらない場合があります。ステートメントは複数行にまたがって記述できるため、次の代入は同等です。

@assign[@var2 "foo" $ "bar"]

@assign[var2 "foo" $ "bar"]

@assign
[@var2 "foo" 
$ "bar"]

@assign
[var2 "foo" 
$ "bar"]

この言語では、変数の値を出力することもできます。問題は、特定のコマンド( @print[...] など)がないことです。変数を書き込むだけで十分です。このような:

@var1 @var2

したがって、コードの出力

@assign[@var1 (1+3)*2]
@assign[@var2 "foo" $ "bar"]
@var1 @var2

は:

8 foobar

Mu文法ファイルから始めて、これまでに書いた文法は次のとおりです。

grammar Grammar;

////////////////
//   PARSER   //
////////////////

file
 : block EOF
 ;

block
 : stat*
 ;

stat
 : assignment
 | print
 ;

assignment
 : ASSIGN LBRACKET variable expr RBRACKET
 ;

print
 : AT ID
 ;

expr
 : expr CONCAT expr #concatExpr
 | expr MUL expr    #mulExpr
 | expr DIV expr    #divExpr
 | expr ADD expr    #addExpr
 | expr SUB expr    #subExpr
 | atom             #atomExpr
 ;

variable
 : AT ID
 | ID
 ;

atom
 : LPARENS expr RPARENS  #parExpr
 | INT                   #intAtom
 | STRING                #stringAtom
 | variable              #variableAtom
 ;

///////////////
//   LEXER   //
///////////////

ASSIGN : AT 'assign' ;

AT : '@' ;

ID : [a-zA-Z_] [a-zA-Z_0-9]* ;

INT
 : [0-9]+
 ;

LBRACKET : '[' ;
RBRACKET : ']' ;
LPARENS : '(' ;
RPARENS : ')' ;

CONCAT : '$' ;
ADD : '+' ;
SUB : '-' ;
MUL : '*' ;
DIV : '/' ;

WS : [ \t\r\n] -> skip ;

COMMENT : '[*' .*? '*]' -> skip ;

STRING : '"' (~["\r\n] | '""')* '"' ;

変数を出力するために、カスタマイズされたビジターを開発しました。visitPrintメソッドにアクセスすると、 ATIDの 2 つのトークンがあることがわかります。

今質問です。

次のコード例ができるように文法を変更するにはどうすればよいですか

@assign[@var1 "one"]
@assign[var2 "two"]
@assign[var3 var1 $ var2] 
Value of var3 is: @var3

この出力を生成しますか?

Value of var3 is: onetwo

目標は、文法で自由なテキストを印刷できるようにすることです。

印刷ルールを書き直さなければならないと思います。しかし... どうやって?

print
 : AT ID
 | ?????? //Help!
 ;

この場合、"Value of var3 is: " が単一のトークンになることも目標です (単語ごとに 1 つのトークンではありません)。

これは確かに間違った方法です!

print
 : AT ID
 | .+?
 ;

前もって感謝します。

4

1 に答える 1

0

これは、Parr の「The Definitive ANTLR 4 Reference」の 12.3 章で XML タグをテキストから分離する例に似ています。彼はレクサーでモードを使用して、XML タグの内側と外側 (つまり、プレーン テキスト) の間でトークン出力を切り替えます。

あなたの場合、「@assign」と「]」がタグとして機能しているように見えます(モード1)。それ以外の場合は、変数を認識した後に入力を出力に出力できます。

于 2013-07-24T17:15:04.873 に答える