用Python在Python中解析重要的空白(特别是Parsley)

时间:2013-04-12 16:38:27

标签: python parsing peg

我正在创建一个支持重要空格的语法(最像是“Z”lisp变种而不是Python或者yaml,但同样的想法)

我遇到了这个article on how to do significant whitespace parsing in a pegasus a PEG parser for C#

但是我把它转换成欧芹并不太成功,看起来Pegasus中的#STATE#变量在某种程度上跟踪了回溯。

这是我最接近一个简单的解析器,如果我使用indent的版本,看看它不能解析子,如果我使用的版本没有,它无法解析兄弟姐妹。

如果这是欧芹的限制,我需要使用PyPEG或Parsimonious或其他东西,我对此持开放态度,但似乎内部缩进变量可以遵循PEG内部回溯,这一切都可行。

import parsley

def indent(s):
    s['i'] += 2
    print('indent i=%d' % s['i'])


def deindent(s):
    s['i'] -= 2
    print('deindent i=%d' % s['i'])


grammar = parsley.makeGrammar(r'''
id = <letterOrDigit+>
eol = '\n' | end
nots = anything:x ?(x != ' ')

node =  I:i id:name eol !(fn_print(_state['i'], name)) -> i, name

#I = !(' ' * _state['i'])
I = (' '*):spaces ?(len(spaces) == _state['i'])
#indent = ~~(!(' ' * (_state['i'] + 2)) nots) -> fn_indent(_state)
#deindent = ~~(!(' ' * (_state['i'] - 2)) nots) -> fn_deindent(_state)

indent = -> fn_indent(_state)
deindent = -> fn_deindent(_state)

child_list = indent (ntree+):children deindent -> children

ntree = node:parent (child_list?):children -> parent, children
nodes = ntree+

''', {
    '_state': {'i': 0},
    'fn_indent': indent,
    'fn_deindent': deindent,
    'fn_print': print,
})

test_string = '\n'.join((
    'brother',
    '  brochild1',
    #'    gchild1',
    #'  brochild2',
    #'    grandchild',
    'sister',
    #'  sischild',
    #'brother2',
))

nodes = grammar(test_string).nodes()

0 个答案:

没有答案