Antlr4 关于在ANTLR 4语法中处理歧义运算符的建议

Antlr4 关于在ANTLR 4语法中处理歧义运算符的建议,antlr4,ambiguous-grammar,Antlr4,Ambiguous Grammar,我正在为basic方言编写一个antlr语法文件。大部分工作都在进行中,或者我对下一步需要做什么有了很好的想法。然而,我根本不确定我应该如何处理用于等式测试和赋值的“=”字符 例如,这是一个有效的语句 t = (x = 5) And (y = 3) 如果x等于5,则进行计算;如果y等于3,则对这些结果执行逻辑“与”,并将结果分配给t 我的语法将解析这个;虽然这是错误的,但我认为,一旦模棱两可的问题得到解决,这将自行解决 如何区分“=”字符的两种用法? 1) 我是否应该从表达式中删除赋值规则

我正在为basic方言编写一个antlr语法文件。大部分工作都在进行中,或者我对下一步需要做什么有了很好的想法。然而,我根本不确定我应该如何处理用于等式测试和赋值的“=”字符

例如,这是一个有效的语句

t = (x = 5) And (y = 3) 
如果x等于5,则进行计算;如果y等于3,则对这些结果执行逻辑“与”,并将结果分配给t

我的语法将解析这个;虽然这是错误的,但我认为,一旦模棱两可的问题得到解决,这将自行解决

如何区分“=”字符的两种用法?
1) 我是否应该从表达式中删除赋值规则,并在代码生成期间在访问者和/或侦听器实现中处理这些情况(赋值与相等测试)

2) 有没有更好的方法来定义语法,这样它就已经被整理好了

有人能简单地告诉我如何最好地实现这种语言的“特性”吗

此外,我一直在阅读ANTLR4的权威指南以及寻找解决方案的语言实现模式。它可能在那里,但我还没有找到

下面是完整的解析器语法。分配令牌当前设置为“=”。“相等”设置为“==”

parser grammar wlParser;

options { tokenVocab=wlLexer; }

program
    :   multistatement (NEWLINE multistatement)* NEWLINE?
    ;

multistatement
    :   statement (COLON statement)*
    ;

statement
    :   declarationStat
    |   defTypeStat
    |   assignment
    |   expression
    ;

assignment
    :   lvalue op=ASSIGN expression
    ;

expression
    :   <assoc=right> left=expression op=CARAT right=expression #exponentiationExprStat
    |   (PLUS|MINUS) expression #signExprStat
    |   IDENTIFIER DATATYPESUFFIX? LPAREN expression RPAREN #arrayIndexExprStat
    |   left=expression op=(ASTERISK|FSLASH) right=expression #multDivExprStat
    |   left=expression op=BSLASH right=expression #integerDivExprStat
    |   left=expression op=KW_MOD right=expression #modulusDivExprStat
    |   left=expression op=(PLUS|MINUS) right=expression #addSubExprStat
    |   left=string op=AMPERSAND right=string #stringConcatenation
    |   left=expression op=(RELATIONALOPERATORS | KW_IS | KW_ISA) right=expression #relationalComparisonExprStat
    |   left=expression (op=LOGICALOPERATORS right=expression)+ #logicalOrAndExprStat
    |   op=KW_LIKE patternString #likeExprStat
    |   LPAREN expression RPAREN #groupingExprStat
    |   NUMBER #atom
    |   string #atom
    |   IDENTIFIER DATATYPESUFFIX? #atom
    ;

lvalue
    :   (IDENTIFIER DATATYPESUFFIX?) | (IDENTIFIER DATATYPESUFFIX? LPAREN expression RPAREN)
    ;

string
    :   STRING
    ;

patternString
    :   DQUOT (QUESTIONMARK | POUND | ASTERISK | LBRACKET BANG? .*? RBRACKET)+ DQUOT
    ;

referenceType
    :   DATATYPE
    ;

declarationStat
    :   constDecl
    |   varDecl
    ;

constDecl
    :   CONSTDECL? KW_CONST IDENTIFIER EQUAL expression
    ;

varDecl
    :   VARDECL (varDeclPart (COMMA varDeclPart)*)? | listDeclPart
    ;

varDeclPart
    :   IDENTIFIER DATATYPESUFFIX? ((arrayBounds)? KW_AS DATATYPE (COMMA DATATYPE)*)?
    ;

listDeclPart
    :   IDENTIFIER DATATYPESUFFIX? KW_LIST KW_AS DATATYPE
    ;

arrayBounds
    :   LPAREN (arrayDimension (COMMA arrayDimension)*)? RPAREN
    ;

arrayDimension
    :   INTEGER (KW_TO INTEGER)?
    ;

defTypeStat
    :   DEFTYPES DEFTYPERANGE (COMMA DEFTYPERANGE)*
    ;
语法分析器;
选项{tokenVocab=wlLexer;}
程序
:多语句(换行符多语句)*换行符?
;
多陈述
:语句(冒号语句)*
;
陈述
:declarationStat
|defTypeStat
|分配
|表情
;
分配
:左值op=赋值表达式
;
表达
:left=表达式op=CARAT right=表达式#指数运算exprstat
|(加|减)表达式#signExprStat
|标识符数据类型后缀?LPAREN表达式RPAREN#arrayindexperstat
|左=表达式op=(星号| FSLASH)右=表达式#multDivExprStat
|左=表达式op=b斜杠右=表达式#integerDivExprStat
|左=表达式op=KW#u MOD right=表达式#moduleusDrivexprstat
|左=表达式op=(加|减)右=表达式#addSubExprStat
|左=字符串op=符号,右=字符串#字符串连接
|左=表达式op=(RELATIONALOPERATORS | KW_IS | KW_ISA)右=表达式#RelationalComparisonNexpstat
|左=表达式(op=LOGICALOPERATORS右=表达式)+#logicalOrAndExprStat
|op=KW#LIKE patternString#likeExprStat
|LPAREN表达式RPAREN#groupingExprStat
|原子数
|字符串#原子
|标识符数据类型后缀#原子
;
左值
:(标识符DATATYPESUFFIX?)|(标识符DATATYPESUFFIX?LPAREN表达式RPAREN)
;
一串
:字符串
;
图案串
:DQUOT(问号“磅”|星号“拍子砰砰”?*?拍子)+DQUOT
;
参考类型
:数据类型
;
声明状态
:constDecl
|瓦尔德克尔
;
康斯特代克
:康斯特德?KW_常量标识符相等表达式
;
瓦尔德克尔
:VARDECL(varDeclPart(逗号varDeclPart)*)listDeclPart
;
瓦尔德卡尔帕特
:标识符DATATYPESUFFIX?((数组边界)?KW_作为数据类型(逗号数据类型)*)?
;
listDeclPart
:标识符DATATYPESUFFIX?KW_将KW_列为数据类型
;
阵列边界
:LPAREN(arrayDimension(逗号arrayDimension)*)?帕伦
;
阵列维数
:整数(千瓦到整数)?
;
defTypeStat
:DEFTYPES DEFTYPERANGE(逗号DEFTYPERANGE)*
;
这是lexer语法

lexer grammar wlLexer;

NUMBER
    :   INTEGER
    |   REAL
    |   BINARY
    |   OCTAL
    |   HEXIDECIMAL
    ;

RELATIONALOPERATORS
    :   EQUAL
    |   NEQUAL
    |   LT
    |   LTE
    |   GT
    |   GTE
    ;

LOGICALOPERATORS
    :   KW_OR
    |   KW_XOR
    |   KW_AND
    |   KW_NOT
    |   KW_IMP
    |   KW_EQV
    ;

INSTANCEOF
    :   KW_IS
    |   KW_ISA
    ;

CONSTDECL
    :   KW_PUBLIC
    |   KW_PRIVATE
    ;

DATATYPE
    :   KW_BOOLEAN
    |   KW_BYTE
    |   KW_INTEGER
    |   KW_LONG
    |   KW_SINGLE
    |   KW_DOUBLE
    |   KW_CURRENCY
    |   KW_STRING
    ;

VARDECL
    :   KW_DIM
    |   KW_STATIC
    |   KW_PUBLIC
    |   KW_PRIVATE
    ;

LABEL
    :   IDENTIFIER COLON
    ;

DEFTYPERANGE
    :   [a-zA-Z] MINUS [a-zA-Z]
    ;

DEFTYPES
    :   KW_DEFBOOL
    |   KW_DEFBYTE
    |   KW_DEFCUR
    |   KW_DEFDBL
    |   KW_DEFINT
    |   KW_DEFLNG
    |   KW_DEFSNG
    |   KW_DEFSTR
    |   KW_DEFVAR
    ;

DATATYPESUFFIX
    :   PERCENT
    |   AMPERSAND
    |   BANG
    |   POUND
    |   AT
    |   DOLLARSIGN
    ;

STRING
    :   (DQUOT (DQUOTESC|.)*? DQUOT)
    |   (LBRACE (RBRACEESC|.)*? RBRACE)
    |   (PIPE (PIPESC|.|NEWLINE)*? PIPE)
    ;

fragment DQUOTESC:          '\"\"' ;
fragment RBRACEESC:         '}}' ;
fragment PIPESC:            '||' ;

INTEGER
    :   DIGIT+ (E (PLUS|MINUS)? DIGIT+)?
    ;

REAL
    :   DIGIT+ PERIOD DIGIT+ (E (PLUS|MINUS)? DIGIT+)?
    ;

BINARY
    :   AMPERSAND B BINARYDIGIT+
    ;

OCTAL
    :   AMPERSAND O OCTALDIGIT+
    ;

HEXIDECIMAL
    :   AMPERSAND H HEXDIGIT+
    ;

QUESTIONMARK:               '?' ;
COLON:                      ':' ;
ASSIGN:                     '=';
SEMICOLON:                  ';' ;
AT:                         '@' ;
LPAREN:                     '(' ;
RPAREN:                     ')' ;
DQUOT:                      '"' ;
LBRACE:                     '{' ;
RBRACE:                     '}' ;
LBRACKET:                   '[' ;
RBRACKET:                   ']' ;
CARAT:                      '^' ;
PLUS:                       '+' ;
MINUS:                      '-' ;
ASTERISK:                   '*' ;
FSLASH:                     '/' ;
BSLASH:                     '\\' ;
AMPERSAND:                  '&' ;
BANG:                       '!' ;
POUND:                      '#' ;
DOLLARSIGN:                 '$' ;
PERCENT:                    '%' ;
COMMA:                      ',' ;
APOSTROPHE:                 '\'' ;
TWOPERIODS:                 '..' ;
PERIOD:                     '.' ;
UNDERSCORE:                 '_' ;
PIPE:                       '|' ;
NEWLINE:                    '\r\n' | '\r' | '\n';
EQUAL:                      '==' ;
NEQUAL:                     '<>' | '><' ;
LT:                         '<' ;
LTE:                        '<=' | '=<';
GT:                         '>' ;
GTE:                        '=<'|'<=' ;

KW_AND:                     A N D ;
KW_BINARY:                  B I N A R Y ;
KW_BOOLEAN:                 B O O L E A N ;
KW_BYTE:                    B Y T E ;
KW_DATATYPE:                D A T A T Y P E ;
KW_DATE:                    D A T E ;
KW_INTEGER:                 I N T E G E R ;
KW_IS:                      I S ;
KW_ISA:                     I S A ;
KW_LIKE:                    L I K E ;
KW_LONG:                    L O N G ;
KW_MOD:                     M O D ;
KW_NOT:                     N O T ;
KW_TO:                      T O ;
KW_FALSE:                   F A L S E ;
KW_TRUE:                    T R U E ;
KW_SINGLE:                  S I N G L E ;
KW_DOUBLE:                  D O U B L E ;
KW_CURRENCY:                C U R R E N C Y ;
KW_STRING:                  S T R I N G ;

fragment BINARYDIGIT:       ('0'|'1') ;
fragment OCTALDIGIT:        ('0'|'1'|'2'|'3'|'4'|'5'|'6'|'7') ;
fragment DIGIT:             '0'..'9' ;
fragment HEXDIGIT:          ('0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' | A | B | C | D | E | F) ;
fragment A:                 ('a'|'A');
fragment B:                 ('b'|'B');
fragment C:                 ('c'|'C');
fragment D:                 ('d'|'D');
fragment E:                 ('e'|'E');
fragment F:                 ('f'|'F');
fragment G:                 ('g'|'G');
fragment H:                 ('h'|'H');
fragment I:                 ('i'|'I');
fragment J:                 ('j'|'J');
fragment K:                 ('k'|'K');
fragment L:                 ('l'|'L');
fragment M:                 ('m'|'M');
fragment N:                 ('n'|'N');
fragment O:                 ('o'|'O');
fragment P:                 ('p'|'P');
fragment Q:                 ('q'|'Q');
fragment R:                 ('r'|'R');
fragment S:                 ('s'|'S');
fragment T:                 ('t'|'T');
fragment U:                 ('u'|'U');
fragment V:                 ('v'|'V');
fragment W:                 ('w'|'W');
fragment X:                 ('x'|'X');
fragment Y:                 ('y'|'Y');
fragment Z:                 ('z'|'Z');

IDENTIFIER
    :   [a-zA-Z_][a-zA-Z0-9_~]*
    ;


LINE_ESCAPE
    :   (' ' | '\t') UNDERSCORE  ('\r'? | '\n')
    ;

WS
    :   [ \t] -> skip
    ;
lexer语法wlLexer;
数
:整数
|真实的
|二进制的
|八进制
|十六进制
;
关系运算符
:相等
|奈夸尔
|中尉
|LTE
|燃气轮机
|GTE
;
逻辑运算子
:千瓦或
|千瓦异或
|千瓦及
|千瓦不
|千瓦/小时
|千瓦当量
;
瞬间
:千瓦
|瓦努伊萨
;
康斯特代克
:KW_公共
|KW_私人酒店
;
数据类型
:KW_布尔值
|千瓦字节
|千瓦整
|千瓦长
|单千瓦
|双倍千瓦
|千瓦货币
|千瓦串
;
瓦尔德克尔
:千瓦/分
|千瓦静态
|KW_公共
|KW_私人酒店
;
标签
:标识符冒号
;
除型范围
:[a-zA-Z]减去[a-zA-Z]
;
脱模
:KW_DEFBOOL
|千瓦字节
|功率单位
|千瓦/平方英尺
|千瓦定义
|功率单位
|功率定义
|功率单位
|德夫瓦
;
数据类型后缀
:百分比
|符号
|砰
|磅
|在
|美元符号
;
一串
:(DQUOT(DquoteESC)*?DQUOT)
|(LBRACE(rbracesc |)*?RBRACE)
|(管道(管道C |.|新线)*?管道)
;
片段dquoteEsc:“\”\”;
片段rbracesc:'}}';
碎片管道C:“| |”;
整数
:数字+(E(加减)?数字+?
;
真实的
:数字+期间数字+(E(加|减)?数字+?
;
二元的
:安培和B二进制数字+
;
八进制
:安培和O八进制数字+
;
十六进制
:安培和H六位数字+
;
问号:“?”;
冒号:':';
分配:'=';
分号:';';
在:“@”;
LPAREN:'(';
RPAREN:')';
DQUOT:“”;
LBRACE:“{”;
RBRACE:'}';
勒布朗:“[”;
RBRACKET:']';
克拉:“^”;
加:“+”;
减:'-';
星号:'*';
FSLASH:“/”;
b斜杠:“\\”;
符号“&”;
砰:“!”;
英镑:“#”;
美元符号:“$”;
百分比:“”;
逗号:
grammar Foo;

program:
    (statement | exprOtherThanEquality)*
    ;

statement:
    assignment
    ;

expr:
    equality | exprOtherThanEquality
    ;

exprOtherThanEquality:
    boolAndOr
    ;

boolAndOr:
    atom (BOOL_OP expr)*
    ;

equality:
    atom EQUAL expr
    ;

assignment:
    VAR EQUAL expr ENDL
    ;

atom:
    BOOL | 
    VAR | 
    INT |
    group
    ;

group:
    LEFT_PARENTH expr RGHT_PARENTH
    ;

ENDL         : ';' ;
LEFT_PARENTH : '(' ;
RGHT_PARENTH : ')' ;
EQUAL        : '=' ;

BOOL:
    'true' | 'false'
    ;

BOOL_OP:
    'and' | 'or'
    ;

VAR:
    [A-Za-z_]+ [A-Za-z_0-9]*
    ;

INT:
    '-'? [0-9]+
    ;

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