在python中prolog事实词法分析器

时间:2014-06-30 11:19:42

标签: python prolog lexical-analysis

我有兴趣能够使用python

阅读和操纵prolog'事实'

为了方便这一点,如何在python中编写一个可以从文本文件中读取一组事实的词法分析器?

一组事实可能看起来像:

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

1 个答案:

答案 0 :(得分:4)

我喜欢使用pyparsing模块在​​python中创建这种性质的解析器。 Pyparsing是一个解析器组合库;通过将其他解析器组合在一起来构造解析器。这是一个使用pyparsing的示例解析器,它将解析您的输入数据(它将无法解析任何prolog事实,但我认为这将是一个很好的起点):

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']