2012-02-13 12 views
2

私は、命令リストコードを使用するインタープリタを作成しています。私は、ラベル付きの文法を書くときにいくつか問題があります。ANTLR文法 - ラベルと命令の構文解析

私はこのコードブロックパーサしたいと思います:あなたはこれらのラベルは指示せずに、単一の行にありますが、パーサの言語I'haveがで「ラベル+命令」を可能に見ることができるように

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 

をライン。だから、命令とラベルの組み合わせの3貴様の種類があります。

  1. 命令
  2. レーベル:
  3. レーベル:命令

は、私は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に慣れていませんが、 "instruction:(ID ':')?ID_INST operand;"を行う方がきれいだったと思います。 –

+0

@ 500-InternalServerError、残念ながらANTLRでは動作しません:)。 LLパーサでは、左端にオプションのルールを持たないことをお勧めします。 –

+0

おっと!なぜ?しかたがない。 –