2014-06-30 42 views
1

我感興趣的是能夠閱讀和使用python序言其實詞法分析器在Python

爲了便於操縱序言「事實」,怎麼可能用Python語言編寫一個詞法分析器,可以讀出一組事實一個文本文件?

事實的集合可能看起來像:

track(1, 2.0, 4000, 3, 300). 
track(2, 1.0, 9000, 5, 500). 
track(3, 7.0, 9000, 2, 200). 
... 
+1

每一行的格式都與剛纔發佈的行格式一致(如在中,你是否需要能夠解析任意的序言事實,或者只是一個類似於你剛剛發佈的那些)?如果是這樣的話,最好只用手工工具解析器。 – dustyrockpyle

+0

理想情況下任何序言事實 – bph

+1

我寧願去一個乾淨的子集解析。如果你想解析「任意的Prolog事實」,你將需要一個普通的Prolog解析器。這是一個相當雄心勃勃的計劃。這裏是[測試用例](http://www.complang.tuwien.ac.at/ulrich/iso-prolog/conformity_assessment)。 – false

回答

4

我喜歡用pyparsing模塊創建這種性質在Python的解析器。 Pyparsing是一個解析器組合器庫;您通過將其他解析器組合在一起來構造解析器。下面是使用pyparsing,它將分析輸入數據爲例解析器(這將無法解析任何序言的事實,但我認爲這將是一個很好的起點):

import pyparsing as pp 
#relationship will refer to 'track' in all of your examples 
relationship = pp.Word(pp.alphas).setResultsName('relationship') 

number = pp.Word(pp.nums + '.') 
variable = pp.Word(pp.alphas) 
# an argument to a relationship can be either a number or a variable 
argument = number | variable 

# arguments are a delimited list of 'argument' surrounded by parenthesis 
arguments= (pp.Suppress('(') + pp.delimitedList(argument) + 
      pp.Suppress(')')).setResultsName('arguments') 

# a fact is composed of a relationship and it's arguments 
# (I'm aware it's actually more complicated than this 
# it's just a simplifying assumption) 
fact = (relationship + arguments).setResultsName('facts', listAllMatches=True) 

# a sentence is a fact plus a period 
sentence = fact + pp.Suppress('.') 

# self explanatory 
prolog_sentences = pp.OneOrMore(sentence) 

現在我們有一個解析器您在prolog_sentences變量中的輸入。這裏是解析器的一個測試:

test="""track(1, 2.0, 4000, 3, 300). 
track(2, 1.0, 9000, 5, 500). 
track(3, 7.0, 9000, 2, 200).""" 

result = prolog_sentences.parseString(test) 

print result['facts'][0]['arguments'].asList() 
# outputs ['1', '2.0', '4000', '3', '300'] 

print result['facts'][1]['relationship'] 
# outputs 'track' 

print result['facts'][2]['arguments'][1] 
# outputs ['7.0'] 
+0

關於PLY的任何想法? – bph

+1

如果你已經熟悉lex/yacc解析,我會說PLY很棒。我喜歡關於lex/yacc的pyparsing的一件事是,一旦我構造了我的語法,我可以在6個月後回到它,並且能夠快速理解我寫的內容。與PLY相比,Pyparsing爲了可讀性犧牲了簡潔性(可能還有性能)。 – dustyrockpyle