在Python中实现Prolog事实词法分析器

1 投票
1 回答
696 浏览
提问于 2025-04-18 11:34

我想用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 个回答

5

我喜欢使用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']

撰写回答