2017-09-25 65 views
2

我正在開發一個適合配置格式的GUI編輯器。基本上,編輯器將解析配置文件,顯示對象屬性,以便用戶可以從GUI進行編輯,然後將對象寫回文件。解析器保留註釋並從錯誤中恢復

我已經得到了解析 - 編輯 - 寫部分完成,除了:

  • 解析的數據結構只包括對象屬性的信息,所以評論和空格被上寫
  • 丟失,如果有任何語法錯誤,文件的其餘部分被跳過

你會如何解決這些問題?這個問題的常用方法是什麼?我正在使用Python和Parsec模塊https://pythonhosted.org/parsec/documentation.html,但是,我們感謝他們提供幫助和大致方向。

我也試過Pylens(https://pythonhosted.org/pylens/),這是非常接近我所需要的只是它不能跳過語法錯誤。

回答

0

最終,我跑出來的研究時間,並有相當的手動跳過定居。基本上每次解析器失敗時,我們嘗試將光標前進一個字符並重復。不管空白/評論/語法錯誤,流程中跳過的任何部分都將轉儲到Text結構中。代碼是可重複使用的,除了你必須將它合併到所有重複結果的地方以及原始解析器可能會失敗的地方。

下面的代碼,如果它可以幫助任何人。它寫爲Parsy

class Text(object): 
    '''Structure to contain all the parts that the parser does not understand. 
    A better name would be Whitespace 
    ''' 
    def __init__(self, text=''): 
     self.text = text 

    def __repr__(self): 
     return "Text(text='{}')".format(self.text) 

    def __eq__(self, other): 
     return self.text.strip() == getattr(other, 'text', '').strip() 


def many_skip_error(parser, skip=lambda t, i: i + 1, until=None): 
    '''Repeat the original `parser`, aggregate result into `values` 
    and error in `Text`. 
    ''' 
    @Parser 
    def _parser(stream, index): 
     values, result = [], None 

     while index < len(stream): 
      result = parser(stream, index) 
      # Original parser success 
      if result.status: 
       values.append(result.value) 
       index = result.index 
      # Check for end condition, effectively `manyTill` in Parsec 
      elif until is not None and until(stream, index).status: 
       break 
      # Aggregate skipped text into last `Text` value, or create a new one 
      else: 
       if len(values) > 0 and isinstance(values[-1], Text): 
        values[-1].text += stream[index] 
       else: 
        values.append(Text(stream[index])) 
       index = skip(stream, index) 
     return Result.success(index, values).aggregate(result) 
    return _parser 


# Example usage 
skip_error_parser = many_skip_error(original_parser) 

在其他的說明,我想這裏真正的問題是,我使用的是解析器組合庫,而不是一個適當的兩個階段分析的過程。在傳統的解析中,標記器將處理保留/跳過任何空格/註釋/語法錯誤,使它們全部有效地空白並且對解析器不可見。

1

你問到典型的方法解決這個問題。這裏有兩個項目可以解決你所描述的類似問題:

sketch-n-sketch:矢量圖像的「直接操作」界面,您可以在其中編輯描述圖像的源語言,或直接編輯它所表示的圖像並查看這些變化反映在源代碼中。看看視頻演示文稿,它非常酷。

Boomerang:用鏡頭「聚焦」在一些具體的語法的抽象意義,改變這種抽象模型,然後反映原始來源的變化。

兩個項目都取得了幾篇論文描述了他們的作者採取了方式。據我所知,Lens方法非常流行,其中解析和打印成爲Lens的getput函數,該函數採用一些源代碼並專注於該代碼描述的抽象概念。