所以,基本上我的MIPS汇编程序有一些前缀。我使用" 0x"和" $"对于十六进制数字,"#"对于十进制数和"%"对于二进制数。如何构建汇编程序的典型方法。
现在,前缀" 0x"有一点问题。使用匹配" TEXT"的词法分析器规则中断变量定义的规则。例:
[Var1] : 0x2554D
而Var1是TEXT。
我的规则:
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'
我尝试过删除" +"来自TEXT。显然,这似乎有效,但随后变量定义不再正确匹配,只匹配一个字母。我尝试了解决方法,这些都以错误和混乱结束。所以,我认为我可以在这里得到一些帮助。
答案 0 :(得分:1)
每当2个(或更多)词法分析器规则匹配相同的文本时,首先定义的词法优先级将获得优先权。这意味着0x
将被匹配为TEXT
令牌,因为该令牌在VALUE
令牌之前定义。
因此,您还需要在OPCODE_ITYPE
之前移动定义关键字(TEXT
s)的规则,甚至是INT
规则。
答案 1 :(得分:1)
要处理文本和值之间的重叠,请使用模式提供隔离。这里很容易做到,因为括号作为明确的警卫操作。
LBRAKCET : '[' -> pushMode(text) ;
mode text;
TEXT : [a-zA-Z0-9]+ ;
RBRACKET : ']' -> popMode ;
BAD_TEXT : . ;
添加BAD_TEXT作为捕获 - 为您提供了在解析器中处理一些明显错误('var_1')的选项。注意,模式仅在split lexer / parser语法中可用。此外,请勿在解析器规则中使用字符文字,特别是在拆分语法中。