2014-11-03 91 views
0

我正在使用Ply進行教學,我非常喜歡它。 我雖然使用裝飾不重複一些代碼,我想在一些功能。 所以,我嘗試使用下面的代碼:使用python和Ply解析器生成器時出錯

import ply.yacc as yacc 
from functools import wraps 
from CLexer import Lexico 


def producciones(function): 
    """ 
    Decorator for each of the functions which represents 
    grammatical rules. 
    """ 
    variable = function.__doc__.split(':')[0].strip() 
    @wraps(function) 
    def wrapper(*args,**kargs): 
     result = [] 
     for e in args[1][1:]: 
      tmp = Node() 
      if isinstance(e,Node): 
       tmp = e 
      else: 
       tmp.type = str(e) 
      result.append(tmp) 
     tmp = Node(result) 
     tmp.type = variable 
     args[1][0] = tmp 
     function(*args, **kargs) 
     return wrapper 


class Sintaxis: 

    tokens = Lexico.tokens 
    start = 'programa' 
    @producciones 
    def p_program(self, p): 
     """ 
     program : ABREPAREN program CIERRAPAREN program 
     | 
     """ 



    def p_error(self, p): 
     print("Syntax error at '%s'" % p.value) 

    def run(self, s): 
     lexico = Lexico() 
     lexico.build() 
     global tokens 
     self.parser = yacc.yacc(debug = True, module= self) 
     result =self.parser.parse(s,lexico) 
     return result 




if __name__ == '__main__': 
    with open("prueba.txt") as f: 
     texto=f.read() 
    parser = Sintaxis() 
    result = parser.run(texto) 

我的問題是試圖使用的裝飾,這提供了以下錯誤時:

ERROR: new.py:15: Rule 'p_program' requires an argument 

我還沒有發現這個錯誤的文檔中,而方法p_program似乎接受兩個參數......任何線索? 謝謝你的幫助。

+1

返回包裝可能不正確地縮進。 – 2014-11-03 13:51:51

回答

0

讓我們通過您的問題解決問題的源代碼作爲教程。首先讓歷數你的示例代碼之間的差異數量和documentation for PLY

  1. 已使用的語法規則函數
  2. 您已經使用兩個參數的語法規則函數裝飾
  3. 已啓動語法以一個空行
  4. 您已經使用蟒"""串符號規則 - 在手動
  5. 不使用您已經使用空產量在手動
  6. 棄用方式
  7. 您指定的programa開始規則,不存在

這可以通過寫那些單獨和顯示他們的工作或沒有測試每一個示例程序來解決,然後通過消除我們可以推斷出你爲什麼一個錯誤。

幸運的是,PLY發行包含幾個工作示例,可以作爲手冊的附件進行查閱,並且有一些linked from the PLY homepageOne of those examples顯示了使用"""語法指定的規則,並且還爲語法規則函數使用了兩個參數;消除原因2 & 4:

def p_declaration(self, p): 
     """ declaration : decl_body SEMI 
     """ 
     p[0] = p[1] 

如果我們考察更多的與PLY distribution提供的例子中,我們可以發現example\classcalc\calc.py,它具有一個空白行開始的規則,並使用"""語法,也有兩個參數,淘汰的原因2,3 & 4:

def p_expression_binop(self, p): 
     """ 
     expression : expression PLUS expression 
        | expression MINUS expression 
        | expression TIMES expression 
        | expression DIVIDE expression 
        | expression EXP expression 
     """ 

我們需要消除空生產符號的問題。在發行版中的所有示例程序上使用grep都會顯示使用盲目製作的程序。這是BASIC口譯員。這裏(文件examples\BASIC\basparse.py中),我們有以下規則:

def p_optstep(p): 
    '''optstep : STEP expr 
       | empty''' 
    if len(p) == 3: 
     p[0] = p[2] 
    else: 
     p[0] = None 

此規則顯示指定盲目生產的推薦方式,但是手冊中並說:

Note: You can write empty rules anywhere by simply specifying an empty right hand side. However, I personally find that writing an "empty" rule and using "empty" to denote an empty production is easier to read and more clearly states your intentions.

如果我們重寫這個規則符合你的風格,我們可以測試假說:

def p_optstep(p): 
    '''optstep : STEP expr 
       | ''' 
    if len(p) == 3: 
     p[0] = p[2] 
    else: 
     p[0] = None 

實驗結果表明,上述代碼仍然有效,從而消除原因5.我們現在只剩下1的原因& 6.理由6很容易讓你在你的代碼中消除,並且我們留下了理由1.此外,在所有可用的工作PLY示例中,裝飾器的grep不顯示任何。這意味着,即使是專家,也沒有人按照代碼中所示的方式使用裝飾器。我懷疑這是有原因的。他們不工作。 PLY中裝飾器的唯一用法是具有複雜正則表達式的標記。

結論

  1. 停止使用裝飾
  2. 修復開始符號programa
  3. Supply the necessary information when asking for help


[*]在哪裏 lexicoCLexer,哪裏是 prueba.txt?我是否必須定義自己的令牌並編寫自己的詞法分析器,並猜測要分析的文本? 沒有,你應該幫助我。

+0

將問題標記爲MCVE可能是明智的,但在標記> 250個類似問題和標記超時之後,關閉問題的最佳方法是實際回答它! – 2015-05-10 15:08:31

+0

非常感謝,我不能投票回答,但它確實有幫助。我是新手,但從現在開始,我會在發佈之前遵循您的建議並思考問題。 – 2015-05-11 16:04:45

相關問題