我試圖實現一個詞法分析器的樂趣。我已經實現了一個基本的正則表達式匹配器(首先將模式轉換爲NFA,然後轉換爲DFA)。現在我對如何着手毫無頭緒。
我的詞法分析器將採取標記列表及其相應的正則表達式。用來創建詞法分析器的通用算法是什麼?
我想過(或)所有的正則表達式,但我不能確定哪個特定的標記匹配。即使我擴展了我的正則表達式模塊以返回匹配成功時匹配的模式,我如何在匹配器中實現lookahead?
鑑於我已經實現了一個基本的正則表達式匹配器,我該如何實現一個詞法分析器?
回答
假設你有一個工作正則表達式,regex_match
它返回一個布爾值(如果字符串滿足正則表達式,則爲真)。首先,你需要有一個有序的令牌列表(每個有正則表達式)tokens_regex
,這個命令很重要,因爲命令將會規定優先級。
一種算法可以是(這並不一定是隻有一個):
- 寫過程
next_token
它接受一個字符串,並返回所述第一令牌,它的值和剩餘的字符串(或 - 如果是非法/忽略字符 - 無,違規字符和剩餘字符串)。 注意:這必須尊重優先權,並且應該找到最長的標記。 - 編寫一個程序
lex
遞歸調用next_token
。
。
像這樣的東西(用Python編寫的):
tokens_regex = [ (TOKEN_NAME, TOKEN_REGEX),...] #order describes precedence
def next_token(remaining_string):
for t_name, t_regex in tokens_regex: # check over in order of precedence
for i in xrange(len(remaining_string), 0, -1): #check longest possibilities first (there may be a more efficient method).
if regex_match(remaining_string[:i], t_regex):
return t_name, remaining_string[:i], remaining_string[i:]
return None, remaining_string[0], remaining_string[1:] #either an ignore or illegal character
def lex(string):
tokens_so_far = []
remaining_string = string
while len(remaining_string) > 0:
t_name, t_value, string_remaining = next_token(remaining_string)
if t_name is not None:
tokens_so_far.append(t_name, t_value)
#elif not regex_match(t_value,ignore_regex):
#check against ignore regex, if not in it add to an error list/illegal characters
return tokens_so_far
有些東西添加到您的提高詞法分析器:忽略正則表達式,錯誤列表和位置/行號(這些錯誤或令牌)。
玩得開心!祝你好運,解析器:)。
我已經做了幾乎相同的事情。我這樣做的方式是將所有表達式合併到一個非常大的NFA中,並將同一個事件轉換爲一個DFA。這樣做時,可以跟蹤以前在每個對應的原始DFA中接受狀態的狀態及其優先級。
生成的DFA將具有許多正在接受狀態的狀態。您運行此DFA,直到它收到一個沒有相應轉換的字符。如果DFA處於接受狀態,那麼您將查看您的哪個原始NFA具有該接受狀態。具有最高優先級的那個是您要返回的令牌。
這不處理正則表達式lookaheads。無論如何,這些通常不是真正需要詞法分析器的工作。這將是解析器的工作。
這樣的詞法分析器的運行速度與單個正則表達式的速度大致相同,因爲基本上只有一個DFA可以運行。您可以省略完全轉換NFA以獲得更快速的構造算法,但運行速度更慢。該算法基本相同。
我寫的詞法分析器的源代碼是github上的freely available,如果你想看看我是怎麼做到的。
謝謝,我會看看它。不幸的是,我想我需要重寫我的DFA和NFA類,以實現一種機制來跟蹤哪些DFA匹配字符串。 – Likhit
- 1. 基本實現的正則表達式模式匹配行爲
- 2. 如何實現簡化的正則表達式匹配器?
- 3. 我想實現一個有效的正則表達式模式
- 4. 如何在實現正則表達式分析器時實現點(。)符號?
- 5. DFA與正則表達式在實現詞法分析器時的作用?
- 6. 返回一個列表,我已經有一個rowmapper實現
- 7. 找到匹配的正則表達式的第一次出現另一個正則表達式的第一次出現已經發現後
- 8. 正則表達式匹配單詞的第一次出現
- 9. 如何讓我的正則表達式實現我的目標?
- 10. 正則表達式:匹配一個單詞和一個長度
- 11. 在Node/V8中如何實現正則表達式匹配?
- 12. 正則表達式:只匹配單詞出現一次
- 13. 我如何「grep」可以匹配一個正則表達式
- 14. 我如何匹配這是一個正則表達式
- 15. 正則表達式實現
- 16. 正則表達式 - 匹配一組詞
- 17. Java匹配器:如何匹配多個行與一個正則表達式
- 18. 正則表達式匹配兩個詞
- 19. 最短正則表達式匹配(如果已經是另一個匹配項的一部分)
- 20. 正則表達式分裂來實現分詞
- 21. 正則表達式匹配第一個發現價值
- 22. python正則表達式只匹配第一個實例
- 23. 正則表達式僅匹配第一個實例
- 24. Python正則表達式;匹配最後一個實例
- 25. 正則表達式分裂一個詞
- 26. 正則表達式匹配兩個單詞或至少一個
- 27. 正則表達式匹配兩個詞在一個字符串
- 28. 在詞法分析器中正則表達式匹配的問題
- 29. 我該如何實現一個Javascript顏色選擇器
- 30. 我不知道如何實現一個遞歸語法分析器
我對這種方法的關注是它的效率。不會在字符串的子字符串上運行regex_match需要很多時間? – Likhit
另外,我認爲next_token中的return語句應該是'return t_name,remaining_string [:i],remaining_string [i:]'。是的,解析器將是我的下一個練習。 – Likhit
你很對!固定。 –