Несколько других комментариев к вашему парсеру:
Как правило, вам следует избегать определения литералов, которые объединяют ключевые слова с соответствующей пунктуацией. Например, определение arg как Suppress('arg(')
будет искать специально для "arg()", если между ключевым словом и открывающей скобкой есть пробелы. Вместо этого я рекомендую определять ваши ключевые слова с помощью класса Keyword. Вы можете подавить их, если хотите, но ключевое слово обеспечит полное совпадение слова и защитит от случайного совпадения ведущего «val» из «valpref».
Определение ID как Word(alphanums)
откроет дверь для путаницы между ID и целочисленными значениями. Я ожидаю, что идентификаторы всегда будут начинаться как минимум с буквенного символа, поэтому вы можете использовать форму Word с двумя аргументами, чтобы указать альфа только как набор разрешенных начальных символов, а буквенные числа как набор разрешенных символов тела.
См. мой комментарий к вашему сообщению: setName()
vs setResultsName()
Я немного перенастроил ваш парсер, чтобы все команды имели одинаковые клавиши: "cmd" и "args". Это позволяет писать полиморфный код, например цикл for в конце этого примера.
from pyparsing import *
LPAR,RPAR,DOT,COMMA = map(Suppress,"().,")
arg,attack,pref,val,valpref,support = map(Keyword,
"arg att pref val valpref support".split())
ID = Word(alphas, alphanums)
id_pair = Group(ID + COMMA + ID)
integer = Word(nums)
int_pair = Group(integer + COMMA + integer)
arg_cmd = Group(arg("cmd") + LPAR + ID("args") + RPAR)
attack_cmd = Group(attack("cmd") + LPAR + id_pair("args") + RPAR)
pref_cmd = Group(pref("cmd") + LPAR + id_pair("args") + RPAR)
val_cmd = Group(val("cmd") + LPAR + Group(ID + COMMA + integer)("args") + RPAR)
valpref_cmd = Group(valpref("cmd") + LPAR + int_pair("args") + RPAR)
support_cmd = Group(support("cmd") + LPAR + id_pair("args") + RPAR)
apx = OneOrMore((arg_cmd | attack_cmd | pref_cmd | val_cmd | valpref_cmd | support_cmd) + DOT)
for command in apx.parseString(apxSource):
print command.dump()
print command.cmd
print command.args
Если вы хотите следовать своему первоначальному плану именования, я думаю, это будет выглядеть примерно так.
arg_cmd = Group(arg + LPAR + ID("arg") + RPAR)
attack_cmd = Group(attack + LPAR + id_pair("attack") + RPAR)
pref_cmd = Group(pref + LPAR + id_pair("pref") + RPAR)
val_cmd = Group(val + LPAR + Group(ID + COMMA + integer)("val") + RPAR)
valpref_cmd = Group(valpref + LPAR + int_pair("valpref") + RPAR)
support_cmd = Group(support + LPAR + id_pair("support") + RPAR)
Или это.
arg_cmd = (arg + LPAR + ID("arg*") + RPAR)
attack_cmd = (attack + LPAR + id_pair("attack*") + RPAR)
pref_cmd = (pref + LPAR + id_pair("pref*") + RPAR)
val_cmd = (val + LPAR + Group(ID + COMMA + integer)("val*") + RPAR)
valpref_cmd = (valpref + LPAR + int_pair("valpref*") + RPAR)
support_cmd = (support + LPAR + id_pair("support*") + RPAR)
Как видите, существует множество подходов к созданию этих синтаксических анализаторов и результирующих анализируемых структур, вращающихся вокруг личного стиля, а также правильного и неправильного. В последних двух примерах не определены имена «cmd» или «args», поэтому вам придется удалить их из приведенного выше примера кода цикла for. Если вы ищете dict-key, например синтаксический анализ, я думаю, что последняя структура будет больше всего похожа на то, что вы ищете. Однако обратите внимание, что этот синтаксический анализатор отбрасывает порядок, в котором находятся команды. Если порядок важен, вам, вероятно, следует использовать один из первых двух примеров, поскольку классы Group сохранят порядок команд без изменений.
person
PaulMcG
schedule
09.06.2015
setName()
(которое называет выражение, полезное для переопределения сгенерированного по умолчанию имени выражения, используемого в исключениях синтаксического анализа) сsetResultsName()
(которое называет результаты, определяя ключи, подобные dict в результатах анализа). После того, как вы исправите это, вы можете еще больше навести порядок, используя вызываемую форму — заменитеexpr.setResultsName("xyzzy")
наexpr("xyzzy")
. - person PaulMcG   schedule 09.06.2015result['arg']
), я получаю только окончательное значениеarg
из входного потока. - person robobbo   schedule 09.06.2015.setResultsName("arg",listAllMatches=True)
. - person PaulMcG   schedule 10.06.2015setResultsName
и аналогичному синтаксису__call__()
: pythonhosted.org/ pyparsing/ и pythonhosted.org/pyparsing/ - person PaulMcG   schedule 10.06.2015