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