2012-10-18 88 views
0

我正在爲一組CFG編寫解析器。 (注:RHS只能是大寫字母)Javacc解析'<UPPER_CASE><ARROW>

/*忽略聲明之類的東西,這裏的*/

void 
start(): 
{ 
} 
{ 
    (
    <UPPER_CHAR> 
    <ARROW> 
    <STRING> 
    (<PIPE> <STRING>)* 
    )* 
} 


TOKEN: 
{ 
<ARROW: "=>" > 
| 
<PIPE: "|"> 
| 
<UPPER_CHAR: (["A"-"Z"])> 
} 

TOKEN: {<STRING: (<LETTER> | <DIGIT> | <SYMBOL>)+ > } 

這顯然錯過了一些邊緣情況的代碼的主要部分,其中一些包括:

A => A | a | D E => e

所以我做了什麼錯?

回答

1

我猜SYMBOL包含「=」和「>」,但不包括「|」。在這種情況下。 STRING將匹配整個「D E => e」。

爲什麼你想要STRING呢?爲什麼不做這樣的事情。

void start() : {} { 
    (
     <UPPER_CHAR> <ARROW> 
     choices() 
    )* 
} 
void choices() : {} { 
     choice() (<PIPE> choice())* 
} 
void choice() : {} { 
    LOOKAHEAD(<UPPER_CHAR> <ARROW>) 
    {} 
| 
    (<UPPER_CHAR> | <LOWER_CHAR>) choice() 
| 
    {} 
} 

我用遞歸choice的原因是,有沒有辦法使用語法先行退出循環。即你想要的是(<UPPER_CHAR> | <LOWER_CHAR>)*,但是隻要接下來的兩個標記是<UPPER_CHAR> <ARROW>,你就想退出這個循環。