ANTLR4十六进制解析

时间:2015-11-30 04:33:30

标签: c# parsing antlr4 antlr4cs

我在调试ANTLR语法时遇到问题我正在为Gameboy Assembly工作。 它似乎正常工作,但由于某些原因,它在某些边缘情况下无法处理十六进制的0x表示法。

如果我的输入字符串是" JR 0x10" antlr在输入'没有可行的替代方案时失败了。错误。据我了解,这意味着我要么没有规则来解析令牌流,要么就是' 0x'没有被正确理解。如果我使用" JR $ 10" (我支持的备用符号之一)它完美无缺。但是' 0x'和' $'在同一规则中表达。

这是我的g4文件:

grammar GBASM;

eval : exp EOF;
exp : exp op | exp sys | op | sys;

sys : include | section | label | data;
op : monad | biad arg | triad arg SEPARATOR arg;

monad : NOP|RLCA|RRCA|STOP|RLA|RRA|DAA|CPL|SCF|CCF|HALT|RETI|DI|EI|RST|RET;

biad : INC|DEC|SUB|AND|XOR|OR|CP|POP|PUSH|RLC|RRC|RL|RR|SLA|SRA|SWAP|SRL|JP|JR;

triad : RET|JR|JP|CALL|LD|LDD|LDI|LDH|ADD|ADC|SBC|BIT|RES|SET;

arg : (register|value|negvalue|flag|offset|jump|memory);

memory : MEMSTART (register|value|jump) MEMEND;

offset : register Plus value | register negvalue;

register : A|B|C|D|E|F|H|L|AF|BC|DE|HL|SP|HLPLUS|HLMINUS;

flag : NZ | NC | Z | C;

data : DB db;
db : string_data | value | string_data SEPARATOR db | value SEPARATOR db;
include : INCLUDE string_data;
section : SECTION string_data SEPARATOR HOME '[' value ']';

string_data: STRINGLITERAL;
jump : LIMSTRING;
label : LIMSTRING ':';

Z : 'Z';

A : 'A';
B : 'B';
C : 'C';
D : 'D';
E : 'E';
F : 'F';
H : 'H';
L : 'L';
AF : 'AF';
BC : 'BC';
DE : 'DE';
HL : 'HL';
SP : 'SP';
NZ : 'NZ';
NC : 'NC';

value : HexInteger | Integer;
negvalue : (Neg Integer) | (Neg HexInteger);


Neg : '-';
Plus : '+';
HexInteger : (HexPrefix HexDigit+) | (HexDigit+ HexPostfix);

Integer : Digit+;

fragment Digit : ('0'..'9');

HLPLUS : 'HL+' | 'HLI';
HLMINUS : 'HL-' | 'HLD';
MEMSTART : '(';
MEMEND : ')';

LD : 'LD' | 'ld';
JR : 'JR' | 'jr';
JP : 'JP' | 'jp';
OR : 'OR' | 'or';
CP : 'CP' | 'cp';
RL : 'RL' | 'rl';
RR : 'RR' | 'rr';
DI : 'DI' | 'di';
EI : 'EI' | 'ei';

DB : 'DB';

LDD : 'LDD' | 'ldd';
LDI : 'LDI' | 'ldi';
ADD: 'ADD' | 'add';
ADC : 'ADC' | 'adc';
SBC : 'SBC' | 'sbc';
BIT : 'BIT' | 'bit';
RES : 'RES' | 'res';
SET : 'SET' | 'set';
RET: 'RET' | 'ret';
INC : 'INC' | 'inc';
DEC : 'DEC' | 'dec';
SUB : 'SUB' | 'sub';
AND : 'AND' | 'and';
XOR : 'XOR' | 'xor';
RLC : 'RLC' | 'rlc';
RRC : 'RRC' | 'rrc';
POP: 'POP' | 'pop';

SLA : 'SLA' | 'sla';
SRA : 'SRA' | 'sra';

SRL : 'SRL' | 'srl';
NOP : 'NOP' | 'nop';
RLA : 'RLA' | 'rla';
RRA : 'RRA' | 'rra';
DAA : 'DAA' | 'daa';
CPL : 'CPL' | 'cpl';
SCF : 'SCF' | 'scf';
CCF : 'CCF' | 'ccf';
LDH : 'LDH' | 'ldh';
RST : 'RST' | 'rst';
CALL : 'CALL' | 'call';

PUSH : 'PUSH' | 'push';

SWAP : 'SWAP' | 'swap';
RLCA : 'RLCA' | 'rlca';
RRCA : 'RRCA' | 'rrca';
STOP : 'STOP 0' | 'STOP' | 'stop 0' | 'stop';
HALT: 'HALT' | 'halt';
RETI: 'RETI' | 'reti';

HOME: 'HOME';
SECTION: 'SECTION';
INCLUDE: 'INCLUDE';

fragment HexPrefix : ('0x' | '$');
fragment HexPostfix : ('h' | 'H');
fragment HexDigit : ('0'..'9'|'a'..'f'|'A'..'F');
STRINGLITERAL : '"' ~["\r\n]* '"';
LIMSTRING : ('_'|'a'..'z'|'A'..'Z'|'0'..'9')+;
SEPARATOR : ',';
WS : (' '|'\t'|'\n'|'\r') ->channel(HIDDEN);
COMMENT : ';' ~('\n'|'\r')* '\r'? '\n' ->channel(HIDDEN);

在失败的情况下,看起来我终止于' op',在通过案例中,它正确地向下钻取到'值'我的解析器会窃取信息。我错过了一些ANTLR4语法的怪癖吗?

如果相关,我会生成一个C#解析器。

1 个答案:

答案 0 :(得分:0)

事实证明这是我的十六进制规则的顺序。

我没有看到任何变化的原因是因为Visual Studio正在查看我的语法的旧副本(因为Microsofts文件路径系统有点......替代)。

我修改后的语法完美无缺。

谢谢!