2014-03-06 49 views
3

自從畢業以來我一直沒有正式使用建築語言或解析器,並且忘記了當時我所知道的大部分內容。我現在有一個可能從這樣的事情中受益的項目,但我不知道如何處理以下情況。野牛和語法:回放解析堆棧

假設在我想解析的語言中,有一個表示「在表達式中生成隨機浮點數」的標記。

exp: NUMBER 
     {$$ = $1;} 
    | NUMBER PLUS exp 
     {$$ = $1 + $3;} 
    | R PLUS exp 
     {$$ = random() + $3;} 
    ; 

我也想要一個「list」生成操作符,它將重新評估一個「exp」次數。可能是這樣的:

listExp: NUMBER COLON exp 
    { 
     for (int i = 0; i < $1; i++) { 
      print $3; 
     } 
    } 
    ; 

我看到的問題是「exp」在循環開始時已經減少了。如果我有輸入

2 : R + 2 

那麼我想作爲「EXP」被解析和2加入到將產生的隨機數 - 可以說,結果是2.0055。然後在列表表達式中,我認爲2.0055會打印出兩次。

有沒有辦法在評估之前標記「exp」,然後按照列表循環計數的要求多次解析它?這個想法是在每次評估中得到一個不同的隨機數。

回答

4

最好的辦法是在解析結束時構建AST並評估整個AST。在線評估僅適用於非常簡單的項目(即「類似計算器」)項目。

代替AST,您可以爲堆棧或三地址虛擬機構建代碼。這通常更有效,特別是如果你打算經常執行代碼,但是AST的構造要簡單得多,並且執行它是一次深度優先掃描。

0

根據您的語言設計,至少有5個不同的點可以將語言中的標記綁定到某個值。它們是:

  1. 預處理器(如C#定義)
  2. 詞法:識別令牌
  3. 分析器:識別標記的結構,輸出AST
  4. 語義分析:分析AST,分配類型和轉換等
  5. 代碼生成:輸出可執行代碼或直接執行代碼。

如果您有一個可以多次出現的令牌,並且您希望每次都爲其指定一個不同的隨機值,那麼階段4就是要做到這一點的地方。如果您生成AST,請走樹並分配值。如果您直接進入代碼生成(或解釋器),那麼請執行此操作。