📜  PLY (Python lex-Yacc) – 简介

📅  最后修改于: 2022-05-13 01:54:40.061000             🧑  作者: Mango

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

这些功能包括:

  1. LALR(1) 解析
  2. 语法验证
  3. 支持空制作
  4. 广泛的错误检查能力
  5. 歧义解决

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