跳转到主要内容

基于正则表达式的一个简单词法分析器

项目描述

Lexery

Continuous integration Coverage PyPI - version PyPI - Python Version

一个基于正则表达式的简单词法分析器。

灵感来源于 https://eli.thegreenplace.net/2013/06/25/regex-based-lexical-analysis-in-python-and-javascript

用法

您定义词法规则,lexery将迭代地进行查找

>>> import lexery
>>> import re
>>> text = 'crop \t   ( 20, 30, 40, 10 ) ;'
>>>
>>> lexer = lexery.Lexer(
...     rules=[
...         lexery.Rule(identifier='identifier',
...             pattern=re.compile(r'[a-zA-Z_][a-zA-Z_]*')),
...         lexery.Rule(identifier='lpar', pattern=re.compile(r'\(')),
...         lexery.Rule(identifier='number', pattern=re.compile(r'[1-9][0-9]*')),
...         lexery.Rule(identifier='rpar', pattern=re.compile(r'\)')),
...         lexery.Rule(identifier='comma', pattern=re.compile(r',')),
...         lexery.Rule(identifier='semi', pattern=re.compile(r';'))
...     ],
...     skip_whitespace=True)
>>> tokens = lexer.lex(text=text)
>>> assert tokens == [[
...     lexery.Token('identifier', 'crop', 0, 0),
...     lexery.Token('lpar', '(', 9, 0),
...     lexery.Token('number', '20', 11, 0),
...     lexery.Token('comma', ',', 13, 0),
...     lexery.Token('number', '30', 15, 0),
...     lexery.Token('comma', ',', 17, 0),
...     lexery.Token('number', '40', 19, 0),
...     lexery.Token('comma', ',', 21, 0),
...     lexery.Token('number', '10', 23, 0),
...     lexery.Token('rpar', ')', 26, 0),
...     lexery.Token('semi', ';', 28, 0)]]

请注意,如果文本的一部分无法匹配,将引发一个 lexery.Error 异常

>>> import lexery
>>> import re
>>> text = 'some-identifier ( 23 )'
>>>
>>> lexer = lexery.Lexer(
...     rules=[
...         lexery.Rule(identifier='identifier', pattern=re.compile(r'[a-zA-Z_][a-zA-Z_]*')),
...         lexery.Rule(identifier='number', pattern=re.compile(r'[1-9][0-9]*')),
...     ],
...     skip_whitespace=True)
>>> tokens = lexer.lex(text=text)
Traceback (most recent call last):
...
lexery.Error: Unmatched text at line 0 and position 4:
some-identifier ( 23 )
    ^

如果您指定了一个 unmatched_identifier,所有未匹配的字符都将累积在该标识符的令牌中

>>> import lexery
>>> import re
>>> text = 'some-identifier ( 23 )-'
>>>
>>> lexer = lexery.Lexer(
...     rules=[
...         lexery.Rule(identifier='identifier', pattern=re.compile(r'[a-zA-Z_][a-zA-Z_]*')),
...         lexery.Rule(identifier='number', pattern=re.compile(r'[1-9][0-9]*')),
...     ],
...     skip_whitespace=True,
...     unmatched_identifier='unmatched')
>>> tokens = lexer.lex(text=text)
>>> assert tokens == [[
...     lexery.Token('identifier', 'some', 0, 0),
...    lexery.Token('unmatched', '-', 4, 0),
...    lexery.Token('identifier', 'identifier', 5, 0),
...    lexery.Token('unmatched', '(', 16, 0),
...    lexery.Token('number', '23', 18, 0),
...    lexery.Token('unmatched', ')-', 21, 0)]]

安装

  • 使用pip安装lexery

pip3 install lexery

开发

  • 查看仓库。

  • 在仓库根目录中创建虚拟环境

python3 -m venv venv3
  • 激活虚拟环境

source venv3/bin/activate
  • 安装开发依赖项

pip3 install -e .[dev]

预提交检查

我们提供一组预提交检查,包括运行单元测试、代码格式化检查和代码风格检查。

具体来说,我们使用

  • yapf进行格式化检查。

  • 使用pydocstyle检查文档字符串的风格。

  • 使用mypy进行静态类型分析。

  • 使用pylint进行各种代码风格检查。

从已激活的开发依赖的虚拟环境中本地运行预提交检查

./precommit.py
  • 预提交脚本还可以自动格式化代码

./precommit.py  --overwrite

版本控制

我们遵循语义版本控制。版本号X.Y.Z表示

  • X是主版本(不兼容向后版本),

  • Y是次版本(兼容向后版本),

  • Z是补丁版本(兼容向后版本的问题修复)。

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分发

lexery-1.2.0.tar.gz (5.3 kB 查看哈希值)

上传时间

由以下支持