最近開始學習javacc決議器。我被要求撰寫一個決議器,其中一個令牌從 1 到多個數字,另一個令牌從 2 到多個數字因此我想出了這樣的東西:
TOKEN : {
<NUM1: <NUM> (<NUM>)* > //for one or more
<NUM2: (<NUM>) > //for two or more
<NUM :(["0"-"9"]) >
// and in the function
void calc():
{}
{
(
(<NUM1>)
(<NUM2>)
)* <EOF>
}
但是,即使我傳遞了一個沒有數字的文本值,它也會成功傳遞。我在這做錯了什么?
uj5u.com熱心網友回復:
詞法標記的 JavaCC 語法允許您在范圍內包含重復的元素,()后跟以下之一:
? - zero or one time
* - zero or more times
- one or more times
在您的情況下,您需要兩個令牌:
TOKEN:
{
<NUM2: ["0"-"9"] (["0"-"9"]) > // for two or more
<NUM1: (["0"-"9"]) > // for one or more
}
你讀成這樣:
- 令牌命名
NUM1匹配從一位到無限位數 - 令牌命名
NUM2匹配從兩位到無限位數
JavaCC 中的詞法機制使用輸入字符流中的一個字符并嘗試識別標記。兩個自動機如下:

在詞法分析器在兩個自動機的兩個標記同時進行。在不可能有??更多進展之后,識別出最新找到的令牌。如果更多的一個標記型別是可能的,那么一個宣布第一個被認可的。為此,NUM2在 之前宣告NUM1。這意味著對于輸入1令牌NUM2將不會被識別,因為它需要多于一位。在這種情況下NUM1,將是唯一一種與此輸入匹配的令牌型別。對于輸入,12兩種標記型別都將接受它,但NUM2將被識別,因為它首先宣告。這意味著如果您訂購它們NUM1首先,NUM2您將永遠不會收到NUM2令牌,因為NUM1它將始終以最高優先級“獲勝”。
要使用它們,您可以有兩個決議器函式,如下所示:
void match_one_to_many_numbers() : {} { <NUM1> (" " <NUM1>)* <EOF> }
void match_two_to_many_numbers() : {} { <NUM2> (" " <NUM2>)* <EOF> }
你讀成這樣:
- 函式
match_one_to_many_numbers接受從1到無窮多個 tokenNUM1,以空格分隔,然后輸入流必須以EOF系統 token結束 - 功能
match_two_to_many_numbers相同,僅來自令牌NUM2
因為這兩個標記都接受無限數量的數字,所以如果沒有不是數字的分隔符,就不能擁有這些標記的序列。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/314413.html
上一篇:新變數的字符決議
