ANTLR4中PROGRAM令牌未被识别,被判定为ID的问题求助
解决ANTLR4中PROGRAM关键字被识别为ID令牌的问题
问题场景
编写了名为BajaPower的ANTLR4语法文件,定义了PROGRAM等关键字令牌,但使用测试代码验证时,代码开头的“program”被识别为ID令牌,而非定义的PROGRAM令牌。
原语法文件
grammar BajaPower; // Gramaticas programa:PROGRAM ID ';' vars* bloque ; vars:VAR ((ID|ID',')+ ':' tipo ';')+; tipo:(INT|FLOAT); bloque:'{' estatuto+ '}'; estatuto: (asignacion|condicion|escritura); asignacion: ID '=' expresion ';'; condicion: 'if' '(' expresion ')' bloque (';'|'else' bloque ';'); escritura: 'print' '(' (expresion|STRING ',')* (expresion|STRING) ')' ';'; expresion: exp ('>'|'<'|'<>') exp; exp: (termino ('+'|'-')*|termino); termino: (factor ('*'|'/')*|factor); factor: ('(' expresion ')')|('+'|'-') varcte| varcte; varcte: (ID|CteI|CteF); // Tokens WS: [\t\r\n]+ -> skip; PROGRAM:'program'; ID:([a-zA-Z]['_'(a-zA-Z0-9)+]*); VAR:'var'; INT:'int'; FLOAT:'float'; CteI: ([1-9][0-9]*|'0'); CteF: [+-]?([0-9]*[.])?[0-9]+; STRING:'"' [a-zA-Z0-9]+ '"';
测试代码
program TestCorrect; var x,y:int; z:float; { x = 1; y = 2; z = (x+y*3)/4; if (z > x) { print("hola mundo",(x+y)); } }
问题原因
ANTLR4词法分析器遵循两个核心匹配规则:
- 优先匹配最长的输入序列(最长匹配原则);
- 当多个规则匹配长度相同的输入时,定义在前的规则会被优先选用。
原语法中ID规则定义在PROGRAM、VAR等关键字规则之前,而"program"完全符合ID的匹配模式,因此词法分析器会优先将其识别为ID令牌。
解决方案
将所有关键字令牌规则(PROGRAM、VAR、INT、FLOAT)移动到ID规则的前面,确保关键字规则先被匹配。
修改后的语法文件(令牌部分调整)
// Tokens WS: [\t\r\n]+ -> skip; PROGRAM:'program'; VAR:'var'; INT:'int'; FLOAT:'float'; ID:([a-zA-Z]['_'(a-zA-Z0-9)+]*); CteI: ([1-9][0-9]*|'0'); CteF: [+-]?([0-9]*[.])?[0-9]+; STRING:'"' [a-zA-Z0-9]+ '"';
调整后,当输入"program"时,会优先匹配PROGRAM规则,而非ID规则,即可解决识别错误的问题。
内容的提问来源于stack exchange,提问作者Mauroruffo
相关产品推荐
相关产品推荐

