Pyparsing indentedBlock - PullRequest
       11

Pyparsing indentedBlock

0 голосов
/ 13 декабря 2018

Я пытаюсь использовать «indentedBlock» на основе следующего кода:

import pyparsing as pp
import pprint

class Parser(object):
def __init__(self):
    indentStack = [1]
    stmt = pp.Forward()
    start = pp.Word(pp.alphanums + "/" + "\." + "-" + ":" + "!" + "*"+" ")
    funcDecl = (pp.OneOrMore(start)+ pp.restOfLine)
    func_body = pp.indentedBlock(stmt, indentStack)
    funcDef = pp.Group(funcDecl + func_body)
    stmt << (funcDef)
    self.__parser = pp.OneOrMore(stmt)

def parse(self, line):
    try:
        res = self.__parser.parseString(line)
        pprint.pprint(res)
        print("done")
    except pp.ParseException as x:
        print(x)

После применения я получил следующую ошибку:

Ожидаемый W: (ABCD ...) (на символе 226), (строка: 6, столбец: 37)

Основной вид:

if __name__ == "__main__":
parser = Parser()

test = """first level config parameter 1-n
 second level config parameter 1-n
  thirt level config parameter 1-n
 second level config parameter 1-n
  thirt level  config parameter 1-n
first level config parameter 1-n"""

print(test)
parser.parse(test)

Любые идеи, что пошло не так

1 Ответ

0 голосов
/ 14 декабря 2018

Синтаксический разбор, чувствительный к пробелам, всегда является проблемой с pyparsing, учитывая его поведение по умолчанию пропуска пробелов.Кроме того, определение выражения как Word, допустимые символы которого включают ' ', обычно вызывает проблемы.Но так как это заключено в indentedBlock (что позаботится о поиске новых строк в нужных местах), вам может это сойти с рук здесь.

Я расширил вашу тестовую строку, добавив в нее несколько пустых строки несколько многострочных блоков, и придумал это:

import pyparsing as pp

test = """\
first level config parameter 1-n
 second level config parameter 1-n

  thirt level config parameter 1-n
  thirt level config parameter n+1-m

 second level config parameter 1-n
  thirt level  config parameter 1-n
first level config parameter 1-n"""

import pyparsing as pp

indent_stack = [1]
func_body = pp.Forward()
# what you had as `start` looks like pretty much just any line of characters
stmt = pp.Word(pp.printables + " ")
func_body <<= pp.Group(stmt + pp.indentedBlock(func_body | stmt, indent_stack))

# parse your sample text and output results with pprint
pp.OneOrMore(func_body | pp.Group(stmt)).parseString(test).pprint()

Дает:

[['first level config parameter 1-n',
  [[['second level config parameter 1-n',
     [['thirt level config parameter 1-n'],
      ['thirt level config parameter n+1-m']]]],
   [['second level config parameter 1-n',
     [['thirt level  config parameter 1-n']]]]]],
 ['first level config parameter 1-n']]
...