ANTLR4-具有不可识别标记的语言

ANTLR4-具有不可识别标记的语言,antlr4,Antlr4,我正在为一种古老的语言编写语法 这门语言相当复杂,但我想把重点放在一个特定的问题上,所以我做了一个简单的版本。 轻型版本允许指定赋值语句和简单表达式,如数学运算或字符串串联 像这样: @assign[@var1 (1+3)*2] @assign[@var2 "foo" $ "bar"] @var1 @var2 注意:在赋值语句中,变量不能以@char开头。语句也可以写在多行上,因此以下赋值是等效的: @assign[@var2 "foo" $ "bar"] @assign[var2

我正在为一种古老的语言编写语法

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

像这样:

@assign[@var1 (1+3)*2]
@assign[@var2 "foo" $ "bar"]    
@var1 @var2
注意:在赋值语句中,变量不能以@char开头。语句也可以写在多行上,因此以下赋值是等效的:

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

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

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

@assign
[var2 "foo" 
$ "bar"]
在这种语言中,您还可以打印出变量的值。问题是没有特定的命令(如@print[…]),它足以写入变量。像这样:

@assign[@var1 (1+3)*2]
@assign[@var2 "foo" $ "bar"]    
@var1 @var2
所以,代码的输出

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

以下是我从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

现在回答问题。

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

@assign[@var1 "one"]
@assign[var2 "two"]
@assign[var3 var1 $ var2] 
Value of var3 is: @var3
生成此输出

Value of var3 is: onetwo
目标是使语法能够打印一些自由文本

我想我必须重写打印规则。但是怎么做

print
 : AT ID
 | ?????? //Help!
 ;
在本例中,目标也是“var3的值为:”应该是单个标记(而不是每个单词一个标记)

这肯定是错误的方式

print
 : AT ID
 | .+?
 ;

提前感谢。

这看起来类似于Parr的“最终ANTLR 4参考”第12.3章中从文本中分离XML标记的示例。他使用lexer中的模式在内部XML标记和外部XML标记(即纯文本)之间切换令牌输出


在您的情况下,“@assign”和“]”似乎是您的标记(模式1),否则您可以在识别变量后将输入打印到输出。

感谢您的回复!我已经尝试过遵循词汇模式的方式(我在语言的其他方面也使用了该功能),但无论如何,我还没有达到目标。因此,我决定使用@@[…]更改print语句的语法来标识它。