Бесконечный цикл при попытке простого выражения indentedBlock в pyparsing - PullRequest
1 голос
/ 16 октября 2019

Я пытаюсь проанализировать блоки с отступами с помощью pyparsing и indentedBlock

Здесь мой код

from pyparsing import *

indent_stack = [1]
line = ungroup(restOfLine)
block = ungroup(indentedBlock(line, indent_stack))

# Work
data = """  foo
  bar
  tar
"""

block.parseString(data).pprint()

Проблема в том, что parseString не вернется. Кажется, я жду большего ввода или, может быть, я попал в бесконечный цикл. Если я помещу однонитированную строку в блок, начинаю работать

data = """  foo
  bar
  tar

end
"""

Но я хочу иметь возможность разобрать до не смещенной строки (рабочий случай) или до конца строки (не рабочий случай)

Ответы [ 2 ]

1 голос
/ 17 октября 2019

Это ошибка в pyparsing. indentedBlock использует OneOrMore внутренне для реализации повторения встроенных строк. Но restOfLine не перестает работать, если он находится в конце строки, и поэтому, как только вы доберетесь до конца строки, повторение indentedBlock просто продолжит находить пустые restOfLine s, и поэтому indentedBlock простоциклы навсегда.

Обходной путь, пока эта ошибка не будет исправлена ​​и выпущена, состоит в том, чтобы изменить определение line с:

line = ungroup(restOfLine)

на

line = ungroup(~StringEnd() + restOfLine)
0 голосов
/ 16 октября 2019

Я не мог понять, почему именно код делает это. Я даже пытался запустить его в режиме отладки и сделать паузу, но он даже не остановился, чтобы увидеть, где он застревает.

Обходной путь, который вы могли бы использовать сейчас, - это изменение данных для добавления неиспользуемогострока:

from pyparsing import *

indent_stack = [1]
line = ungroup(restOfLine)
block = ungroup(indentedBlock(line, indent_stack))

# Work
data = """  foo
  bar
  tar
"""

block.parseString(data + "\nend").pprint()

# Result: [['foo'], ['bar'], ['tar']]
...