Структура вывода ParseResults с повторяющимися именованными токенами: как сохранить порядок в именованном словаре - PullRequest
1 голос
/ 12 июля 2020

Рассмотрим созданный мной следующий код, который отражает мою проблему (после моего предыдущего вопроса: Как анализировать группы с помощью оператора и скобок ):

from pyparsing import *

line = 'a(1)->b(2)->c(3)->b(4)->a(5)'

LPAR, RPAR = map(Suppress, "()")
num = Word(nums)
SEQOP = Suppress('->')

a = Group(Literal('a')+LPAR+num+RPAR)('ela*')
b = Group(Literal('b')+LPAR+num+RPAR)('elb*')
c = Group(Literal('c')+LPAR+num+RPAR)('elc*')

element = a | b | c

one_seq_expr = Group(element + (SEQOP + element)[...])('one_seq_expr')

out = one_seq_expr.parseString(line)

print(out.dump())

Из этого кода Я получаю следующие результаты:

[[['a', '1'], ['b', '2'], ['c', '3'], ['b', '4'], ['a', '5']]]
- one_seq_expr: [['a', '1'], ['b', '2'], ['c', '3'], ['b', '4'], ['a', '5']]
  - ela: [['a', '1'], ['a', '5']]
    [0]:
      ['a', '1']
    [1]:
      ['a', '5']
  - elb: [['b', '2'], ['b', '4']]
    [0]:
      ['b', '2']
    [1]:
      ['b', '4']
  - elc: [['c', '3']]
    [0]:
      ['c', '3']

Мы можем получить доступ к результатам разными способами:

>> out[0]
([(['a', '1'], {}), (['b', '2'], {}), (['c', '3'], {}), (['b', '4'], {}), (['a', '5'], {})], {'ela': [(['a', '1'], {}), (['a', '5'], {})], 'elb': [(['b', '2'], {}), (['b', '4'], {})], 'elc': [(['c', '3'], {})]})
>> out['one_seq_expr']
([(['a', '1'], {}), (['b', '2'], {}), (['c', '3'], {}), (['b', '4'], {}), (['a', '5'], {})], {'ela': [(['a', '1'], {}), (['a', '5'], {})], 'elb': [(['b', '2'], {}), (['b', '4'], {})], 'elc': [(['c', '3'], {})]})
>> out['one_seq_expr'][0:4]
[(['a', '1'], {}), (['b', '2'], {}), (['c', '3'], {}), (['b', '4'], {})]
>> for _ in out[0]: print(_)
['a', '1']
['b', '2']
['c', '3']
['b', '4']
['a', '5']
>> out['one_seq_expr']['ela']
([(['a', '1'], {}), (['a', '5'], {})], {})

Объект ParseResults out['one_seq_expr'] сохраняет порядок различных найденных токенов. С другой стороны, структура именованных токенов группирует их по имени и сохраняет порядок появления для каждого имени. имя в определенной форме? Что-то вроде:

- one_seq_expr: [['a', '1'], ['b', '2'], ['c', '3'], ['b', '4'], ['a', '5']]
  - ela_0: [['a', '1']]
    [0]:
      ['a', '1']
  - elb_0: [['b', '2']]
    [0]:
      ['b', '2']
  - elc_0: [['c', '3']]
    [0]:
      ['c', '3']
  - elb_1: [['b', '4']]
    [0]:
      ['b', '4']
  - ela_0: [['a', '5']]
    [0]:
      ['a', '5']

Или мы должны использовать ParseResults.getName() в упорядоченном списке токенов out['one_seq_expr']? Например:

>> [_.getName() for _ in out['one_seq_expr']]
['ela', 'elb', 'elc', 'elb', 'ela']

1 Ответ

1 голос
/ 12 июля 2020

Вы можете использовать действие синтаксического анализа, чтобы аннотировать эти элементы соответствующими типами, и они будут сохранены с каждым элементом:

- one_seq_expr: [['ELA_TYPE', 'a', '1'], 
                 ['ELB_TYPE', 'b', '2'], 
                 ['ELC_TYPE', 'c', '3'], 
                 ['ELB_TYPE', 'b', '4'], 
                 ['ELA_TYPE', 'a', '5']]
   ... etc. ...
...