PLY (Python lex-Yacc) – 简介
我们都听说过 lex,它是一个生成词法分析器的工具,然后用于标记输入流和 yacc,它是一个解析器生成器,但是在名为 PLY 的包中以单独模块的形式对这两个工具进行了Python实现。
这些模块被命名为 lex.py 和 yacc.py,它们的工作方式类似于原始的 UNIX 工具 lex 和 yacc。
PLY与 UNIX 对应的工作方式不同,它不需要特殊的输入文件,而是直接将Python程序作为输入。传统工具还利用编译器时间困难的解析表,而 PLY 缓存生成的结果并将它们保存以供使用并根据需要重新生成它们。
词典
这是此包中的关键模块之一,因为 yacc.py 的工作还依赖于 lex.py,因为它负责从输入文本生成标记集合,然后使用正则表达式规则识别该集合。
要在您的Python代码中导入此模块,请使用import ply.lex as lex
例子:
假设你写了一个简单的表达式:y = a + 2 * b
当它通过 ply.py 传递时,会生成以下标记
'y','=', 'a', '+', '2', '*', 'b'
这些生成的令牌通常与始终需要的令牌名称一起使用。
#Token list of above tokens will be
tokens = ('ID','EQUAL','ID', 'PLUS', 'NUMBER', 'TIMES','ID' )
#Regular expression rules for the above example
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'
更具体地说,这些可以表示为令牌类型和令牌的元组
('ID', 'y'), ('EQUALS', '='), ('ID', 'a'), ('PLUS', '+'),
('NUMBER', '2'), ('TIMES', '*'), ('NUMBER', '3')
该模块也以 token() 的形式提供了一个外部接口,它从输入中返回有效的令牌。
yacc.py
这个包的另一个模块是 yacc.py,其中 yacc 代表Yet Another Compiler Compiler 。这可用于实现一次性编译器。它提供了许多在 UNIX yacc 中已经可用的特性和一些额外的特性,这些特性使 yacc.py 比传统的 yacc 更具优势
您可以使用以下内容将 yacc 导入您的Python代码import ply.yacc as yacc 。
这些功能包括:
- LALR(1) 解析
- 语法验证
- 支持空制作
- 广泛的错误检查能力
- 歧义解决
yacc.py 也使用显式令牌生成 token() ,它会根据用户需求不断调用它来收集令牌和语法规则。 yacc.py 将抽象语法树 (AST) 作为输出。
优于 UNIX yacc:
Python实现 yacc.py 不涉及代码生成过程,而是使用反射来制作其词法分析器和解析器,从而节省空间,因为它不需要任何额外的编译器构造步骤和代码文件生成。
要从 lex 文件中导入标记,请使用from lex_file_name_here import tokens ,其中标记是 lex 文件中指定的标记列表。
要指定语法规则,我们必须在 yacc 文件中定义函数。相同的语法如下:
def function_name_here(symbol):
expression = expression token_name term
参考:
https://www.dabeaz.com/ply/ply.html