아래는 입력 어셈블리 파일을 구문 분석하는 문법의 축소 버전입니다. 내 문법의 모든 것은 내가 3 개의 문자 (예 : 문법에서 OPCODE와 같은 길이)를 사용하기 전까지는 괜찮습니다. 그래서 Antlr이 LPCEL이 아닌 OPCODE로 일치한다고 가정합니다. 그러나 어떻게해야합니까? 이 위치는 레이블이어야하며 OPCODE가 아니어야합니까? "규칙 대신 일치하는 고정 문자열 길이를 해석하는 Antlr
시험 입력 :
표준 장비에서set a, label1
set b, abc
출력이 제공 : 나는 ANTLRWorks을 통해 디버깅 단계 때
line 2:5 missing EOF at ','
(OP_BAS set a (REF label1)) (OP_SPE set b)
, 나는 그것을 명령 규칙 2를 시작 볼 수 있지만, 기준에로 " abc "가 규칙 3으로 점프 한 다음", "에서 실패합니다.
방대한 왼쪽 분해율로이를 해결할 수 있지만 문법을 매우 읽을 수 없게 만듭니다. 전 가독성과 기능성간에 타협점을 찾기 위해 노력하고 있습니다 (글로벌 백 트랙은 성능에 큰 타격이되지 않습니다).
grammar TestLabel;
options {
language = Java;
output = AST;
ASTLabelType = CommonTree;
backtrack = true;
}
tokens {
NEGATION;
OP_BAS;
OP_SPE;
OP_CMD;
REF;
DEF;
}
program
: instruction* EOF!
;
instruction
: LABELDEF -> ^(DEF LABELDEF)
| OPCODE dst_op ',' src_op -> ^(OP_BAS OPCODE dst_op src_op)
| OPCODE src_op -> ^(OP_SPE OPCODE src_op)
| OPCODE -> ^(OP_CMD OPCODE)
;
operand
: REG
| LABEL -> ^(REF LABEL)
| expr
;
dst_op
: PUSH
| operand
;
src_op
: POP
| operand
;
term
: '('! expr ')'!
| literal
;
unary
: ('+'! | negation^)* term
;
negation
: '-' -> NEGATION
;
mult
: unary (('*'^ | '/'^) unary)*
;
expr
: mult (('+'^ | '-'^) mult)*
;
literal
: number
| CHAR
;
number
: HEX
| BIN
| DECIMAL
;
REG: ('A'..'C'|'I'..'J'|'X'..'Z'|'a'..'c'|'i'..'j'|'x'..'z') ;
OPCODE: LETTER LETTER LETTER;
HEX: '0x' ('a'..'f' | 'A'..'F' | DIGIT)+ ;
BIN: '0b' ('0'|'1')+;
DECIMAL: DIGIT+ ;
LABEL: ('.' | LETTER | DIGIT | '_')+ ;
LABELDEF: ':' ('.' | LETTER | DIGIT | '_')+ {setText(getText().substring(1));} ;
STRING: '\"' .* '\"' {setText(getText().substring(1, getText().length()-1));} ;
CHAR: '\'' . '\'' {setText(getText().substring(1, 2));} ;
WS: (' ' | '\n' | '\r' | '\t' | '\f')+ { $channel = HIDDEN; } ;
fragment LETTER: ('a'..'z'|'A'..'Z') ;
fragment DIGIT: '0'..'9' ;
fragment PUSH: ('P'|'p')('U'|'u')('S'|'s')('H'|'h');
fragment POP: ('P'|'p')('O'|'o')('P'|'p');
우수 다시 감사합니다. 나는 실제로 레퍼런스와 다른 레지스터를 때리는 것을 알고 싶다. 그래서 나는 그것에 대한 단편을 사용하지 않았다. 필자가 제안한 것처럼 규칙을 작성하는 방법에 대해 생각했지만 파서가 이미 3 개의 문자열을 항상 'OPCODE'로 결정한다는 사실을 해결할 수있는 방법이라고 생각합니다. 나는 커스텀 코드에 당신이 추가 한 것을 좋아한다. 전에는 그렇게 보지 못했다. 그래서 매우 유용하다. 다시 한번 감사드립니다. –
문제는 없습니다. @MarkFisher. –