ANTLR4 -具有不可区分标记的语言



我正在为一种古老的语言开发一种语法。

这门语言很复杂,但我想把重点放在一个具体的问题上,所以我做了一个简单的版本。轻版本允许指定赋值语句和简单表达式,如数学运算或字符串连接。

:

@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 : [ trn] -> skip ;
COMMENT : '[*' .*? '*]' -> skip ;
STRING : '"' (~["rn] | '""')* '"' ;

为了打印变量,我开发了一个定制的访问者。通过访问visitPrint方法,我知道有两个令牌:ATID

现在是问题

如何修改我的语法,使下面的示例代码

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

生成这个输出?

Value of var3 is: onetwo

目标是使语法能够打印一些自由文本。

我想我必须重写print规则。但是…如何?

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

在这种情况下,目标也是"Value of var3 is: "应该是单个标记(而不是每个单词一个标记)。

这肯定是错误的方式!

print
 : AT ID
 | .+?
 ;

这看起来类似于Parr的" the Definitive ANTLR 4 Reference"第12.3章中从文本中分离XML标记的例子。他使用词法分析器中的模式在XML标记内部和外部(即纯文本)之间切换令牌输出。

在您的示例中,似乎"@assign"one_answers"]"作为您的标记(模式1),否则您可以在识别变量后将输入打印到输出。

相关内容

  • 没有找到相关文章

最新更新