使用 python ply 进行部分解析

Partial parsing with python ply

提问人:raywib 提问时间:8/17/2023 最后编辑:raywib 更新时间:8/20/2023 访问量:47

问:

有没有一种简单的方法可以使用 python ply 执行部分解析? 换句话说:与其一次解析整个源,不如解析高达 一个表情的结束,它的结果和交还控制权?yield

例如,以下玩具语法产生预期的 输出。

import ply.lex as lex
import ply.yacc as yacc

data = '''\
a sentence.  another
sentence.
'''

tokens = ('WORD', 'DOT')

t_WORD = r'\w+'
t_DOT = r'\.'
t_ignore = ' \t\n'

lexer = lex.lex()

def p_text(p):
    '''text : text sentence DOT
            | sentence DOT'''
    p[0] = '\n'.join(p[1:-1])

def p_sentence(p):
    '''sentence : sentence WORD
                | WORD'''
    p[0] = ' '.join(p[1:])

parser = yacc.yacc()
print(parser.parse(data))      # parses all sentences at once!

但是,如何才能逐句消费(就像使用生成器一样)而不是全部 一次句子?

# intended behaviour: does not work!
for sent in parser.partial_parse(data):
    do_something_with(sent)
python 解析 yacc ply

评论

0赞 Piotr Siupa 8/21/2023
通常,对于标准 YACC,我会建议使用拉式解析器,但我不知道 PLY 是否支持它。

答:

0赞 Michael Dyck 8/18/2023 #1

当 PLY 解析器在函数的文档字符串中识别出生产实例时,将调用每个函数。因此,在您的示例中,每次解析器识别出 .如果要在每次之后暂停,只需在 中插入暂停即可。例如:p_p_sentencesentencesentencep_sentence

def p_sentence(p):
    '''sentence : sentence WORD
                | WORD'''
    p[0] = ' '.join(p[1:])
    input(f"p_sentence just recognized {p[0]!r} Hit Enter to continue...")