2014-03-27 159 views
0

我正在Python中學習詞法分析器。我正在使用Ply庫進行一些字符串的詞法分析。我爲一些C++語言語法實現了以下詞法分析器。詞法分析

但是,我正面臨一個奇怪的行爲。當我在其他函數定義的末尾定義評論states function definitions時,代碼工作正常。如果我在定義其他定義之前定義了評論state functions,那麼只要輸入字符串中的// sectoin開始,就會收到錯誤。

這是什麼原因?

import ply.lex as lex 

tokens = (
     'DLANGLE',  # << 
     'DRANGLE',  # >> 
     'EQUAL',  # = 
     'STRING',  # "144" 
     'WORD',   # 'Welcome' in "Welcome." 
     'SEMICOLON', # ; 

) 

t_ignore    = ' \t\v\r' # shortcut for whitespace 


states = (
     ('cppcomment', 'exclusive'), # <!-- 
) 



def t_cppcomment(t): # definition here causes errors 
    r'//' 
    print 'MyCOm:',t.value 

    t.lexer.begin('cppcomment'); 



def t_cppcomment_end(t): 
    r'\n' 
    t.lexer.begin('INITIAL'); 


def t_cppcomment_error(t): 
    print "Error FOUND" 
    t.lexer.skip(1) 

def t_DLANGLE(t): 

    r'<<' 
    print 'MyLAN:',t.value 
    return t 

def t_DRANGLE(t): 
    r'>>' 
    return t 

def t_SEMICOLON(t): 

    r';' 
    print 'MySemi:',t.value 
    return t; 

def t_EQUAL(t): 
     r'=' 
     return t 

def t_STRING(t): 
     r'"[^"]*"' 
     t.value = t.value[1:-1] # drop "surrounding quotes" 
     print 'MyString:',t.value 
     return t 

def t_WORD(t): 
     r'[^ <>\n]+' 
     print 'MyWord:',t.value 
     return t 




webpage = "cout<<\"Hello World\"; // this comment" 
htmllexer = lex.lex() 
htmllexer.input(webpage) 
while True: 
     tok = htmllexer.token() 
     if not tok: break 
     print tok 

問候

+0

有人有些見解嗎? –

+0

如果您發佈了您的錯誤樣本,它可能會有所幫助。 –

+1

不生成解釋器錯誤,因爲錯誤由t_cppcomment_error()模塊處理。我的問題是,如果我在最後定義了所有的註釋模塊,但是在註釋模塊在其他模塊 –

回答

0

它,因爲你沒有規則,接受thiscomment ,真的你不關於什麼的評論,你可以easilly這樣做

t_cppcomment_ANYTHING = '[^\r\n]' 

略低於護理你的t_ignore規則

+0

是不是會調用't_WORD()'或't_String()'模塊?他們應該被稱爲,因爲他們被稱爲「Hello World」&cout? –

+0

沒有.. t_STRING需要引號,而t_WORD不能有空格......你可以試試我的解決方案,看看它是否解決了你的問題......還不知道各州是否可以接收未定義的符號 –

+0

只是弄清楚了。由於我已將註釋狀態定義爲排他性,因此它不會使用包含性狀態模塊(如果註釋模塊在頂部定義,否則它由於某種原因而使用它)。因此,您將重新定義所有模塊以進行評論狀態。因此,ply提供了用於跳過未定義特定模塊的字符的error()模塊。 這個問題的目的是找出這個原因。 –

1

只是想出我出來。由於我已將註釋狀態定義爲exclusive,因此它不會使用inclusive狀態模塊(如果註釋模塊在頂部定義,否則由於某種原因使用它)。所以你將有重新定義所有模塊的評論狀態再次。因此一層提供了錯誤()模塊用於跳過未定義特定模塊的字符。

+0

此方法不會使任何除非你想強制你的語言標記的評論... –

+0

@JoranBeasley這個問題的目的不是沒有parsibg評論,原因是找到爲什麼我們在獨佔狀態時得到錯誤。 :) –