私は古い言語の文法を開発しています。
言語はかなり複雑ですが、特定の問題に焦点を当てたいので、軽量バージョンを作成しました。軽量バージョンでは、割り当てステートメントと、数学演算や文字列連結などの単純な式を指定できます。
このような:
@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メソッドにアクセスすると、 ATとIDの 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
| .+?
;
前もって感謝します。