Это проблема?
#match any of the above
item = area ^ category ^ criteria
#keyword to perform action on ALL items
all_ = pp.CaselessLiteral("all")
Должно быть:
#keyword to perform action on ALL items
all_ = pp.CaselessLiteral("all")
#match any of the above
item = area ^ category ^ criteria ^ all_
РЕДАКТИРОВАТЬ - если вам интересно ...
Ваши регулярные выражения настолько похожи, что я подумал, что увижу, как их объединить в одно. Вот фрагмент кода для анализа ваших трехточечных обозначений с помощью одного регулярного выражения, а затем с помощью действия синтаксического анализа, чтобы выяснить, какой тип вы получили:
import pyparsing as pp
dotted_notation = pp.Regex(r'[a-zA-Z](\.\d{1,2}(\.\d{1,2})?)?')
def name_notation_type(tokens):
name = {
0 : "area",
1 : "category",
2 : "criteria"}[tokens[0].count('.')]
# assign results name to results -
tokens[name] = tokens[0]
dotted_notation.setParseAction(name_notation_type)
# test each individually
tests = "A A.1 A.2.2".split()
for t in tests:
print t
val = dotted_notation.parseString(t)
print val.dump()
print val[0], 'is a', val.getName()
print
# test all at once
tests = "A A.1 A.2.2"
val = pp.OneOrMore(dotted_notation).parseString(tests)
print val.dump()
Печать:
A
['A']
- area: A
A is a area
A.1
['A.1']
- category: A.1
A.1 is a category
A.2.2
['A.2.2']
- criteria: A.2.2
A.2.2 is a criteria
['A', 'A.1', 'A.2.2']
- area: A
- category: A.1
- criteria: A.2.2
EDIT2 - я вижу исходную проблему ...
Что вас запутало, так это пропуски незаполненных пробелов в pyparsing. Pyparsing пропустит пробел между определенными токенами, но обратное неверно - для разбора не требуется пробел между отдельными выражениями парсера. Таким образом, в вашей версии all_less «ALL» выглядит как 3 области: «A», «L» и «L». Это верно не только для Regex, но и для любого класса pyparsing. Посмотрите, может ли класс WordEnd pyparsing быть полезным для обеспечения этого.
РЕДАКТИРОВАТЬ3 - Тогда, может быть, что-то вроде этого ...
toggle_item = (toggle + pp.OneOrMore(item)).setParseAction(toggle_item_action)
toggle_all = (toggle + all_).setParseAction(toggle_all_action)
toggle_directive = toggle_all | toggle_item
При форматировании ваших команд вы должны сначала сделать так, чтобы синтаксический анализатор проверял, переключается ли ALL, прежде чем искать отдельные области и т. Д. Если вам нужно поддерживать что-то, что может читать «ENABLE A.1 ALL», тогда используйте негативный прогноз на item
: item = ~all_ + (area ^ etc...)
.
(Обратите внимание, что я заменил item + pp.ZeroOrMore(item)
просто pp.OneOrMore(item)
.)