我编写此脚本是为了解析类似于prolog的语法的语句,将连接词作为具有优先级的运算符:
import pyparsing as pyp
alphabet = "abcdefghijklmnopqrstuvwxyz"
alphabet = alphabet + alphabet.upper()
symbol = pyp.Word(alphabet)
predicate = symbol + "(" + pyp.ZeroOrMore(symbol + ",") + symbol + ")"
parenthetic = pyp.Forward()
pyp_formula = pyp.infixNotation((predicate | parenthetic),
[
(pyp.oneOf('~'), 1, pyp.opAssoc.RIGHT),
(pyp.oneOf(','), 2, pyp.opAssoc.LEFT),
(pyp.oneOf(';'), 2, pyp.opAssoc.LEFT),
(pyp.oneOf('::'), 2, pyp.opAssoc.LEFT),
(pyp.oneOf('->'), 2, pyp.opAssoc.LEFT),
(pyp.oneOf(':-'), 2, pyp.opAssoc.LEFT),
(pyp.oneOf('--'), 1, pyp.opAssoc.LEFT),
(pyp.oneOf('.'), 1, pyp.opAssoc.LEFT),
])
parenthetic << "(" + pyp_formula + ")"
我跑步时
parse = pyp_formula.parseString('d(A, D), e(D) :- f(A), g(D); h(D).')
parse_list = formula_parse.asList()
print(parse_list)
我得到“ d(A,D),e(D)”甚至没有被分成两个谓词,并且“ f(A),g(D); h(D)”被视为一个单数在非终端中。
[[[['d', '(', 'A', ',', 'D', ')', ',', 'e', '(', 'D', ')'],
':-', [['f', '(', 'A', ')', ',', 'g', '(', 'D', ')'],
';', 'h', '(', 'D', ')']], '.']]
我尝试了几种选择,但似乎无法获得正确的解析。
欢迎任何帮助!
答案 0 :(得分:1)
无需定义parenthetic
,infixNotation
可以为您完成。如果您pyp.Group
predicate
表达式,那么符号和符号args将为您分组。 pyparsing也有delimitedList
助手,它是expr, expr, expr
的捷径:使用pyp.delimitedList(expr)
。默认定界符为',',但您可以定义其他定界符。最后,使用这么长的运算符列表,您可能会在进行任何非平凡的解析时遇到性能问题-向ParserElement.enablePackrat()
添加调用以打开内部解析缓存。
以下是这些更改后的代码外观:
import pyparsing as pyp
pyp.ParserElement.enablePackrat()
alphabet = "abcdefghijklmnopqrstuvwxyz"
alphabet = alphabet + alphabet.upper()
symbol = pyp.Word(alphabet)
predicate = pyp.Group(symbol + "(" + pyp.delimitedList(symbol) + ")")
pyp_formula = pyp.infixNotation(predicate,
[
(pyp.oneOf('~'), 1, pyp.opAssoc.RIGHT),
(pyp.oneOf(','), 2, pyp.opAssoc.LEFT),
(pyp.oneOf(';'), 2, pyp.opAssoc.LEFT),
(pyp.oneOf('::'), 2, pyp.opAssoc.LEFT),
(pyp.oneOf('->'), 2, pyp.opAssoc.LEFT),
(pyp.oneOf(':-'), 2, pyp.opAssoc.LEFT),
(pyp.oneOf('--'), 1, pyp.opAssoc.LEFT),
(pyp.oneOf('.'), 1, pyp.opAssoc.LEFT),
])
pyp_formula.runTests(
'''
d(A, D) -> h(D).
d(A, D), e(D) :- f(A), g(D); h(D).
'''
)
结果:
d(A, D) -> h(D).
[[[['d', '(', 'A', 'D', ')'], '->', ['h', '(', 'D', ')']], '.']]
[0]:
[[['d', '(', 'A', 'D', ')'], '->', ['h', '(', 'D', ')']], '.']
[0]:
[['d', '(', 'A', 'D', ')'], '->', ['h', '(', 'D', ')']]
[0]:
['d', '(', 'A', 'D', ')']
[1]:
->
[2]:
['h', '(', 'D', ')']
[1]:
.
d(A, D), e(D) :- f(A), g(D); h(D).
[[[[['d', '(', 'A', 'D', ')'], ',', ['e', '(', 'D', ')']], ':-', [[['f', '(', 'A', ')'], ',', ['g', '(', 'D', ')']], ';', ['h', '(', 'D', ')']]], '.']]
[0]:
[[[['d', '(', 'A', 'D', ')'], ',', ['e', '(', 'D', ')']], ':-', [[['f', '(', 'A', ')'], ',', ['g', '(', 'D', ')']], ';', ['h', '(', 'D', ')']]], '.']
[0]:
[[['d', '(', 'A', 'D', ')'], ',', ['e', '(', 'D', ')']], ':-', [[['f', '(', 'A', ')'], ',', ['g', '(', 'D', ')']], ';', ['h', '(', 'D', ')']]]
[0]:
[['d', '(', 'A', 'D', ')'], ',', ['e', '(', 'D', ')']]
[0]:
['d', '(', 'A', 'D', ')']
[1]:
,
[2]:
['e', '(', 'D', ')']
[1]:
:-
[2]:
[[['f', '(', 'A', ')'], ',', ['g', '(', 'D', ')']], ';', ['h', '(', 'D', ')']]
[0]:
[['f', '(', 'A', ')'], ',', ['g', '(', 'D', ')']]
[0]:
['f', '(', 'A', ')']
[1]:
,
[2]:
['g', '(', 'D', ')']
[1]:
;
[2]:
['h', '(', 'D', ')']
[1]:
.