Пример: У меня есть литералы "альфа", "бета", "гамма". Как заставить pyparsing проанализировать следующие входы:
alpha
alpha|beta
beta|alpha|gamma
Данный ввод может быть построен с использованием одного или нескольких не повторяющихся литералов из заданного набора, разделенных символом "|". Будет оценен совет по настройке пиража.
Используйте '&' оператора для каждого, вместо "+" или "|". Если вы должны иметь все, но в непредсказуемом порядке используйте:
Literal('alpha') & 'beta' & 'gamma'
Если некоторые могут отсутствовать, но каждый из них используется не более одного раза, используйте опции:
Optional('alpha') & Optional('beta') & Optional('gamma')
Ой, я забыл '|' разделители. Один мягкий синтаксический анализатор должен был бы использовать delimitedList:
delimitedList(oneOf("alpha beta gamma"), '|')
Это позволит любой или все ваши варианты, но не защищает от дубликатов. Может быть проще всего использовать синтаксическое действие:
itemlist = delimitedList(oneOf("alpha beta gamma"), '|')
def ensureNoDuplicates(tokens):
if len(set(tokens)) != len(tokens):
raise ParseException("duplicate list entries found")
itemlist.setParseAction(ensureNoDuplicates)
Это похоже на самый простой подход ко мне.
EDIT:
В последних версиях pyparsing были введены условия синтаксического анализа, чтобы облегчить запись такого вида разбора:
itemlist = delimitedList(oneOf("alpha beta gamma"), '|')
itemlist.addCondition(lambda tokens: len(set(tokens)) == len(tokens),
"duplicate list entries found")