所以,基本上我的MIPS汇编程序有几个前缀。我使用"0x"和"$"表示十六进制数,"#"表示十进制数,"%"表示二进制数。汇编程序的典型构建方式。
现在,前缀"0x"中断与变量定义的"TEXT"规则匹配的词法分析器规则存在一个小问题。 例如:
[Var1] : 0x2554D
而 Var1 是文本。
我的规则:
mips32code : instruction+
;
instruction : OPCODE_ITYPE rt COMMA rs COMMA prefix imm # ITypeInstruction
| '[' TEXT ']' ':' prefix imm # VariableDefinition
;
imm : instruction # immformat
| INT # immvalue
;
prefix : instruction # prefixinst
| VALUE # prefixval
;
rs : instruction # rsexpr
| REG # rsreg
;
rt : instruction # rtexpr
| REG # rtreg
;
/* Immediate-Value Lexer */
INT : [0-9A-Fa-f]+
;
/* Text for variable definition and label definition names. */
TEXT : [a-zA-Z0-9]+
;
/* Prefix */
VALUE : ('$'|'0x'|'#'|'%')
;
REG
: [rR] '0'
| [aA] [tT]
| [vV] [01]
| [aA] [0-3]
| [tT] [0-9]
| [sS] [0-8]
| [kK] [01]
| [gG] [pP]
| [sS] [pP]
| [fF] [pP]
| [rR] [aA]
;
COMMA : ','
;
OPCODE_ITYPE
: [aA] [dD] [dD] [iI] // ADDI
| [dD] [aA] [dD] [dD] [iI] // DADDI
| [dD] [aA] [dD] [dD] [iI] [uU] // DADDIU
| [aA] [dD] [dD] [iI] [uU] // ADDIU
| [oO] [rR] [iI] // ORI
| [xX] [oO] [rR] [iI] // XORI
| [sS] [lL] [tT] [iI] // SLTI
| [sS] [lL] [tT] [iI] [uU] // SLTIU
| [aA] [nN] [dD] [iI] // ANDI
;
因此,上述内容无法正常工作。它成功地将上述输入与 Var1 匹配,但说明如下:
ADDIU T0, T1, 0x2544
不起作用,因为"0x"前缀以某种方式中断了 TEXT 词法分析器规则。我收到的错误是:
line 1:14 no viable alternative input 'ADDIU T0, T1, 0x2544'
我已经尝试了一些东西,例如从文本中删除"+"。显然,这似乎有效,但是变量定义不再正确匹配,只匹配一个字母。我尝试了解决方法,但都以错误和混乱告终。所以,我想我可以在这里得到一些帮助。
若要处理文本和值之间的重叠,请使用模式提供隔离。 在这里很容易做到,因为支架作为明确的防护装置运行。
LBRAKCET : '[' -> pushMode(text) ;
mode text;
TEXT : [a-zA-Z0-9]+ ;
RBRACKET : ']' -> popMode ;
BAD_TEXT : . ;
添加BAD_TEXT作为包罗万象 - 让您选择在解析器中处理一些明显的错误("var_1")。 请注意,模式仅在拆分词法分析器/解析器语法中可用。 此外,不要在分析器规则中使用字符文本,尤其是在拆分语法中。
每当 2 个(或更多)词法分析器规则与同一文本匹配时,首先定义的规则将优先。这意味着0x
将作为TEXT
令牌进行匹配,因为该令牌是在VALUE
令牌之前定义的。
因此,您还需要在TEXT
甚至INT
规则之前移动定义关键字(OPCODE_ITYPE
s)的规则。