我感興趣的是能夠閱讀和使用python序言其實詞法分析器在Python
爲了便於操縱序言「事實」,怎麼可能用Python語言編寫一個詞法分析器,可以讀出一組事實一個文本文件?
事實的集合可能看起來像:
track(1, 2.0, 4000, 3, 300).
track(2, 1.0, 9000, 5, 500).
track(3, 7.0, 9000, 2, 200).
...
我感興趣的是能夠閱讀和使用python序言其實詞法分析器在Python
爲了便於操縱序言「事實」,怎麼可能用Python語言編寫一個詞法分析器,可以讀出一組事實一個文本文件?
事實的集合可能看起來像:
track(1, 2.0, 4000, 3, 300).
track(2, 1.0, 9000, 5, 500).
track(3, 7.0, 9000, 2, 200).
...
我喜歡用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']
關於PLY的任何想法? – bph
如果你已經熟悉lex/yacc解析,我會說PLY很棒。我喜歡關於lex/yacc的pyparsing的一件事是,一旦我構造了我的語法,我可以在6個月後回到它,並且能夠快速理解我寫的內容。與PLY相比,Pyparsing爲了可讀性犧牲了簡潔性(可能還有性能)。 – dustyrockpyle
每一行的格式都與剛纔發佈的行格式一致(如在中,你是否需要能夠解析任意的序言事實,或者只是一個類似於你剛剛發佈的那些)?如果是這樣的話,最好只用手工工具解析器。 – dustyrockpyle
理想情況下任何序言事實 – bph
我寧願去一個乾淨的子集解析。如果你想解析「任意的Prolog事實」,你將需要一個普通的Prolog解析器。這是一個相當雄心勃勃的計劃。這裏是[測試用例](http://www.complang.tuwien.ac.at/ulrich/iso-prolog/conformity_assessment)。 – false