簡體   English   中英

用於算術表達式的 JavaCC 解析器示例

[英]Parser example of JavaCC for arithmetic expressions

這是我在解析領域的第一天。 作為我在 JavaCC 中的第一個示例,代碼是

SKIP:  { " " | "\t" | "\n" | "\r"                    }
TOKEN: { "(" | ")" | "+" | "*" | <NUM: (["0"-"9"])+> }

void S(): {} { E() <EOF>           }
void E(): {} { T() ("+" T())*      }
void T(): {} { F() ("*" F())*      }
void F(): {} { <NUM> | "(" E() ")" }

我想知道為什么它可以處理像 int+(int+int) 這樣的情況。 通過它的算法,我認為它會將這個表達式解析為 [int] & [(int] & [int)] 作為 Ts 並且無法解析。 為什么它按預期解析?

將輸入字符串“1+(2+3)”視為一個標記序列

<NUM> "+" "(" <NUM> "+" <NUM> ")" <EOF>

這個序列可以從 S() 推導出如下。 這 。 顯示哪些令牌已被消耗。 隨着令牌被消耗,. 向右移動

         . S() 
           ~~~ expand
     ==> . E() <EOF>
           ~~~ expand
     ==> . T() ("+" T())* <EOF>
           ~~~ expand
     ==> . F() ("*" F())* ("+" T())* <EOF>
           ~~~ expand
     ==> . (<NUM> | "(" E() ")") ("*" F())* ("+" T())* <EOF>
           ~~~~~~~~~~~~~~~~~~~~~ choose first and consume
     ==> <NUM> . ("*" F())* ("+" T())* <EOF>
                 ~~~~~~~~~~ delete
     ==> <NUM> . ("+" T())* <EOF>
                 ~~~~~~~~~~ unroll and consume
     ==> <NUM> "+" . T() ("+" T())* <EOF>
                     ~~~ expand
     ==> <NUM> "+" . F() ("*" F())* ("+" T())* <EOF>
                     ~~~~
     ==> <NUM> "+" . (<NUM> | "(" E() ")") ("*" F())* ("+" T())* <EOF>
                     ~~~~~~~~~~~~~~~~~~~~~ choose second and consume
     ==> <NUM> "+" "(" . E() ")" ("*" F())* ("+" T())* <EOF>
                         ~~ expand
     ==> <NUM> "+" "(" . T() ("+" T())* ")" ("*" F())* ("+" T())* <EOF>
                         ~~~ expand
     ==> <NUM> "+" "(" . F() ("*" F())* ("+" T())* ")" ("*" F())* ("+" T())* <EOF>
                         ~~~ expand
     ==> <NUM> "+" "(" . (<NUM> | "(" E() ")") ("*" F())* ("+" T())* ")" ("*" F())* ("+" T())* <EOF>
                         ~~~~~~~~~~~~~~~~~~~~~ choose first and consume
     ==> <NUM> "+" "(" <NUM> . ("*" F())* ("+" T())* ")" ("*" F())* ("+" T())* <EOF>
                               ~~~~~~~~~~ delete
     ==> <NUM> "+" "(" <NUM> . ("+" T())* ")" ("*" F())* ("+" T())* <EOF>
                               ~~~~~~~~~~~~~~ unroll and consume
     ==> <NUM> "+" "(" <NUM> "+" . T() ("+" T())* ")" ("*" F())* ("+" T())* <EOF>
                                   ~~~ expand
     ==> <NUM> "+" "(" <NUM> "+" . F() ("*" F())* ("+" T())* ")" ("*" F())* ("+" T())* <EOF>
                                   ~~~ expand
     ==> <NUM> "+" "(" <NUM> "+" . (<NUM> | "(" E() ")") ("*" F())* ("+" T())* ")" ("*" F())* ("+" T())* <EOF>
                                   ~~~~~~~~~~~~~~~~~~~~~ choose first and consume
     ==> <NUM> "+" "(" <NUM> "+" <NUM> . ("*" F())* ("+" T())* ")" ("*" F())* ("+" T())* <EOF>
                                         ~~~~~~~~~~ delete
     ==> <NUM> "+" "(" <NUM> "+" <NUM> . ("+" T())* ")" ("*" F())* ("+" T())* <EOF>
                                         ~~~~~~~~~~ delete and consume
     ==> <NUM> "+" "(" <NUM> "+" <NUM> ")" . ("*" F())* ("+" T())* <EOF>
                                             ~~~~~~~~~~ delete
     ==> <NUM> "+" "(" <NUM> "+" <NUM> ")" . ("+" T())* <EOF>
                                             ~~~~~~~~~~ delete and consume
     ==> <NUM> "+" "(" <NUM> "+" <NUM> ")" <EOF> .

鑰匙:

  • expand:用它的定義替換一個非終結符。
  • 選擇:用 S 或 T 替換 (S|T)
  • 展開:將 (S)* 替換為 S (S)*
  • 刪除:將 (S)* 替換為空

上面的推導是左右推導。 我選擇顯示左右派生,因為它反映了 JavaCC 的工作方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM