2012-02-13 3 views
2

Я пишу интерпретатор, который использует код списка инструкций. У меня возникают проблемы, когда я пытаюсь написать грамматику для инструкций с метками.ANTLR Grammar - Разборные ярлыки и инструкции

Я хотел бы парсер этого блока коды:

LD 4 
ST A 
LD A 
EQ 4 
ST _AUX_1 
(* IF *) 
LDN _AUX_1 
JMPC _label_2 
(* THEN *) 
LD B 
EQ 3 
ST _AUX_2 
_label_2: (* ELSE *) 
_label_1: (* END IF*) 
LD TRUE 

Как вы можете видеть эти ярлыки находятся в одной строке без инструкции, но язык I'have для синтаксического анализатора позволяет «ярлык + инструкцию» в линии. Итак, есть три вида Differents комбинаций инструкции и этикетки:

  1. Инструкция
  2. Label:
  3. Label: Инструкция

Я разбором 1 и 2, но я не способный анализировать все различные комбинации.

Это выдержка из моей ANTLR грамматики:

program_il : instruction* ; 

instruction 
     : ID':' // label 
     | ID_INST operand 
     ; 

operando 
    : ID 
    | CTE_INT 
    | CTE_BOOL 
    ; 

Я попытался изменить грамматику:

instruction : (ID':')? instruction? ; 

Но я получил следующую ошибку:

As a result, alternative(s) 2 were disabled for that input 
[14:43:49] error(201): Analizador.g:131:29: The following alternatives can never be matched: 2 

Может ли кто-нибудь помочь мне с этой проблемой? Спасибо заранее.

ответ

1

Потому что вы принимаете Label: Instruction, грамматика неоднозначна. Синтаксический анализатор не может сделать различие между:

lbl: 
LD 4 

и

lbl: LD 4 

Другими словами, вам нужно, чтобы ваши instruction s быть разделены своего рода ограничителем. Прорыв линии будет делать трюк, как следующий демо показывает:

grammar T; 

program_il 
: NL* instruction (NL+ instruction)* NL* EOF 
; 

instruction 
: ID ':' (ID_INST operand)? 
| ID_INST operand 
; 

operand 
: ID 
| CTE_INT 
| CTE_BOOL 
; 

CTE_BOOL 
: 'TRUE' 
| 'FALSE' 
; 

ID_INST 
: 'LD' 
| 'ST' 
| 'EQ' 
| 'LDN' 
| 'JMPC' 
; 

ID 
: ('_' | 'a'..'z' | 'A'..'Z') ('_' | 'a'..'z' | 'A'..'Z' | '0'..'9')* 
; 

CTE_INT 
: ('0'..'9')+ 
; 

NL 
: '\r'? '\n' 
| '\r' 
; 

COMMENT 
: '(*' .* '*)' {skip();} 
; 

SPACE 
: (' ' | '\t')+ {skip();} 
; 

Теперь разбор входа:

(* IF *) 
JMPC _label_2 
(* THEN *) 
LD B 
ST _AUX_2 
_label_2: LDN _AUX_1 (* ELSE *) 
_label_1: (* END IF*) 
LD TRUE 

приведет к следующему дереву:

enter image description here

+0

+1, но , хотя я не знаком с ANTLR, я думаю, что было бы чище делать «инструкцию: (ID ':')? ID_INST operand;». –

+0

@ 500-InternalServerError, увы, это не работает с ANTLR :). С анализаторами LL часто бывает хорошей идеей: * не * иметь необязательные правила с левой стороны. –

+0

Ой! - задается вопросом, почему нет. Ну что ж. –

Смежные вопросы