2013-02-21 66 views
3

我想寫一個簡單解析器的嵌套塊語法,只是分層明文。例如:最簡單的嵌套塊解析器

Some regular text. 
This is outputted as-is, foo{but THIS 
is inside a foo block}. 

bar{ 
    Blocks can be multi-line 
    and baz{nested} 
} 

最簡單的方法是什麼?我已經寫了2個工作實現,但它們過於複雜。我嘗試了全文正則表達式匹配和逐字符分析。

我必須向人們傳授它的運作方式,所以簡單是至關重要的。我不想介紹對Lex/Yacc Flex/Bison(或者PEGjs/Jison,實際上,這是javascript)的依賴。

回答

1

的不錯的選擇可能歸結如下:

  • 鑑於你constaints,這將是遞歸下降。即使沒有限制,這也是一個好方法。
  • 您可以分析char-by-char(傳統)或編寫使用本地字符串庫的詞法層來掃描{}。無論哪種方式,您可能都希望返回三個終端符號加上EOF:BLOCK_OF_TEXT,LEFT_BRACE和RIGHT_BRACE。
+0

是的,我去了遞歸下降。這可能需要一些解釋來闡明這個概念,但在此之後,代碼是非常可讀的,流程是不言而喻的。 – slezica 2013-02-21 13:16:47

1
char c; 

    boolean ParseNestedBlocks(InputStream i) 
     { if ParseStreamContent(i) 
     then { if c=="}" then return false 
          else return true 
       } 
     else return false; 

    boolean ParseSteamContent(InputStream i) 
    { loop: 
     c = GetCharacter(i); 
     if c =="}" then return true; 
     if c== EOF then return true; 
     if c=="{" 
      { if ParseStreamContent(i) 
        { if c!="}" return false; } 
       else return false; 
      } 
     goto loop 
    } 
1

最近,我一直在使用解析器組合在純JavaScript的一些項目。我將代碼抽取到一個單獨的項目中; you can find it here。這種方法類似於@DigitalRoss建議的遞歸下降解析器,但是在解析器特有的代碼和一般解析器記賬代碼之間有更明確的分割。

一個適合您需求的解析器​​(如果我理解正確的您的要求)將是這個樣子:

var open = literal("{"),     // matches only '{' 
    close = literal("}"),     // matches only '}' 
    normalChar = not1(alt(open, close)); // matches any char but '{' and '}' 

var form = new Parser(function() {}); // forward declaration for mutual recursion 

var block = node('block', 
       ['open', open  ], 
       ['body', many0(form)], 
       ['close', close  ]); 

form.parse = alt(normalChar, block).parse; // set 'form' to its actual value 

var parser = many0(form); 

,你會使用這樣的:

// assuming 'parser' is the parser 
var parseResult = parser.parse("abc{def{ghi{}oop}javascript}is great"); 

的解析結果是一個語法樹。

除了回溯,該庫還可以幫助您在解析器調用之間生成漂亮的錯誤消息和線程用戶狀態。後兩個我發現對於生成大括號錯誤消息非常有用,在出現以下情況時,報告問題以及出錯的大括號標記的位置:1)有一個開放的大括號,但沒有關閉; 2)存在不匹配的支具類型 - 即(...]{...); 3)沒有匹配打開的近端大括號。

+0

這是一個非常美麗的抽象!你爲什麼不給它一些額外的文檔工作,並將其製作成圖書館? – slezica 2013-02-22 19:06:06

+0

@uʍopǝpısdn謝謝!終於開始清理它了一下。 – 2013-03-26 14:23:32