PLY是否支持一个解析器使用多个词法分析器?

3
我正在尝试使用PLY实现Python解析器,用于Kconfig语言的解析。该语言用于生成Linux内核的配置选项。
有一个名为"source"的关键字可以执行包含操作。当词法分析器遇到此关键字时,我会改变词法分析器的状态,创建一个新的词法分析器来对被包含的文件进行词法分析:
def t_begin_source(t):
    r'source '
    t.lexer.begin('source')

def t_source_path(t):
    r'[^\n]+\n+'
    t.lexer.begin('INITIAL') 
    global path
    source_lexer = lex.lex(errorlog=lex.NullLogger())
    source_file_name = (path +  t.value.strip(' \"\n')) 
    sourced_file = file(path + t.value.strip(' \"\n')).read()

    source_lexer.input(sourced_file)

    while True:
        tok = source_lexer.token()
        if not tok:
            break

在别处我有这行代码

lexer = lex.lex(errorlog=lex.NullLogger()) 

这是“主”或“根”词法分析器,将由解析器调用。

我的问题是我不知道如何告诉解析器使用不同的词法分析器或告诉“source_lexer”返回什么...

也许应该使用克隆函数...

谢谢

3个回答

2

有趣的是,通过同一次谷歌搜索,我找到了一个链接,解释了如何为PLY解析器编写自己的词法分析器。这篇文章简单明了地解释了它,但只需要四个实例变量和一个单一的token方法。


我也试过那种方法...但最终,建立一个完整的令牌列表并使用自己的getToken函数的解决方案还是不错的... - LB40

2

我不太清楚PLY的细节,但在我建立的其他类似系统中,最合理的做法是有一个单一的词法分析器来管理包括文件的堆栈。因此,词法分析器会返回一个统一的令牌流,打开和关闭遇到的包含文件。


你可以使用词法分析器的 input 方法来重置词法分析器并提供新的输入。在包含的文件完成后,您必须回到原始文件,从您离开的地方继续执行(或者说更多或更少)。 - S.Lott
是的,但我不知道如何将这些标记返回给解析器。 - LB40

0

好的,

所以我做的是建立了一个所有标记的列表,在实际解析之前就已经构建好了。

解析器不再调用词法分析器,因为在调用解析函数时可以使用tokenfunc参数覆盖解析器使用的getToken函数。

result = yacc.parse(kconfig,debug=1,tokenfunc=my_function)

我的函数现在被称为获取下一个标记的函数,它遍历先前构建的标记列表。

考虑到词法分析,当我遇到源关键字时,我会克隆我的词法分析器并更改输入以包括文件。

def sourcing_file(source_file_name):
    print "SOURCE FILE NAME " , source_file_name
    sourced_file = file(source_file_name).read()
    source_lexer = lexer.clone()
    source_lexer.input(sourced_file)
    print 'END OF SOURCING FILE'

    while True:
        tok = source_lexer.token()
        if not tok:
            break
        token_list.append(tok)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接