Pyparsing не группирует эти токены, потому что вы этого не сказали. Поведение Pyparsing по умолчанию состоит в том, чтобы просто объединить все совпадающие токены в один список. Чтобы получить группировку ваших токенов, оберните выражения в вашем синтаксическом анализаторе, которые должны быть сгруппированы, в выражение Group
, содержащее pyparsing. В вашем случае измените series
с:
series = hand + Optional(greater | through + hand)
до
series = Group(hand + Optional(greater | through + hand))
Кроме того, я рекомендую вам не реализовывать свой собственный список с разделителями-запятыми, как вы это делали в series
, а вместо этого использовать помощник по переносу, delimitedList
:
hand_range = delimitedList(series)
delimitedList
предполагает использование разделителей запятых, но в качестве аргумента delim
может быть задан любой символ (или даже полное выражение преобразования). Сами разделители исключаются из результатов, так как delimitedList
предполагает, что разделители существуют просто как разделители между важными битами, элементами списка.
После внесения этих двух изменений результаты анализа теперь начинают выглядеть так, как вы просите:
[['2', '2', '+'], ['A', 'K', 'o', '-', 'A', 'T', 'o'], ['K', 'Q', 'z']]
Я предполагаю, что вы также можете поместить Group
вокруг определения hand
, чтобы также структурировать эти результаты.
Если это выражение будет каким-либо образом оцениваться (например, покерная комбинация), тогда, пожалуйста, посмотрите на эти примеры в вики-редакторе, которые используют классы в качестве действий синтаксического анализа для создания объектов, которые можно оценить для ранга или логического значение или что-то еще.
http://pyparsing.wikispaces.com/file/view/invRegex.py
http://pyparsing.wikispaces.com/file/view/simpleBool.py
http://pyparsing.wikispaces.com/file/view/eval_arith.py
Если вы создаете объекты для этих выражений, вам не нужно использовать Group
.