造个轮子用Python写个编程语言指定中文语法&打包发布

2023年 8月 21日 72.0k 0

前言

okey,到这里的话,就要到尾声了。当然这里要说明的是,这个项目也是基于这个项目 进行的二次开发,然后我按照自己的理解进行说明改动。当然项目本身比较简单,所以只花了差不多三天的时间搞懂了。那么到后期有时间的话,我会给它引入对象类型,更高级的内置函数。这一点主要是因为实现起来确实更复杂,有更多的语法规则和细节要处理。不过对于这一部分功能我并不着急,后期慢慢实现就可以,作为毕设的话,这个也只是第一部分,还有后面的部分。没办法还有一个身份,Java全干工程师。

中英文双语法

okey,那么废话不多说,我们直接开始吧,这个的话,昨天想了一坤时,觉得,既然是中文编程,但是这个中文有时候太别扭了,所以直接那是支持中英文吧。

所以在这里的话,对关键字做了处理:

首先是定义这个新的的关键字
在这里的的话,定义了新的这个关键字,和标点符号。然后重新里面比较和contains方法。

class KeyWord:

    def __init__(self,ek,ck):
        self.ex = ek
        self.ck = ck

    def __contains__(self, value):
        # 如果value等于ex或ck中的任意一个,返回True;否则返回False
        return value == self.ex or value == self.ck

    def __eq__(self, other):
        # 如果ex或ck有一个相等,则两个对象相等
        return self.ex == other.ex or self.ck == other.ck

    def __ne__(self, other):
        # 如果ex和ck都不相等,则两个对象不相等
        return not (self.ex == other.ex or self.ck == other.ck)


class Punctuation:
    def __init__(self,ep,cp):
        self.ep = ep
        self.cp = cp

    def __contains__(self, value):
        return value == self.ep or value == self.cp

    def __eq__(self, other):
        return self.ep == other.ep or self.cp == other.cp

    def __ne__(self, other):
        return not (self.ep == other.ep or self.cp == other.cp)

这样一来的话,对于这个符号,和关键字就可以做到很好地比对了,实现效果的话,就是可以这样编程:
在这里插入图片描述

然后的话,是定义这个:

PUNCTUATIONS = {
    ',':Punctuation(',',','),
    '(':Punctuation('(','('),
    ')':Punctuation(')',')'),
    '[':Punctuation('[','【'),
    ']':Punctuation(']','】'),
    ';':Punctuation(';',';'),
}


KEYWORDSEC = {

    'var':KeyWord('var','设'),
    '设':KeyWord('var','设'),
    'and':KeyWord('and','且'),
    '且':KeyWord('and','且'),
    'or':KeyWord('or','或'),
    '或':KeyWord('or','或'),
    'not':KeyWord('not','否'),
    '否':KeyWord('not','否'),
    'if':KeyWord('if','如果'),
    '如果':KeyWord('if','如果'),
    'elif':KeyWord('elif','再者'),
    '再者':KeyWord('elif','再者'),
    'else':KeyWord('else','不然'),
    '不然':KeyWord('else','不然'),
    'for':KeyWord('for','遍历'),
    '遍历':KeyWord('for','遍历'),
    'to':KeyWord('to','到'),
    '到':KeyWord('to','到'),
    'step':KeyWord('step','步长'),
    '步长':KeyWord('step','步长'),
    'while':KeyWord('while','循环'),
    '循环':KeyWord('while','循环'),
    'fun':KeyWord('fun','函数'),
    '函数':KeyWord('fun','函数'),
    'then':KeyWord('then','就'),
    '就':KeyWord('then','就'),
    'end':KeyWord('end','结束'),
    '结束':KeyWord('end','结束'),
    'return':KeyWord('return','返回'),
    '返回':KeyWord('return','返回'),
    'continue':KeyWord('continue','继续'),
    '继续':KeyWord('continue','继续'),
    'break':KeyWord('break','终止'),
    '终止':KeyWord('break','终止'),
}



KEYWORDS = [
    'var',
    '设',
    'and',
    '且',
    'or',
    '或',
    'not',
    '否',
    'if',
    '如果',
    'elif',
    '再者',
    'else',
    '不然',
    'for',
    '遍历',
    'to',
    '到',
    'step',
    '步长',
    'while',
    '循环',
    'fun',
    '函数',
    'then',
    '就',
    'end',
    '结束',
    'return',
    '返回',
    'continue',
    '继续',
    'break',
    '终止'
]


这里需要把前面的关键字都这样改过来。

不过这里注意的是,我们的这些内置函数的话,还是英文的,主要是如果也要改成中文的话,这个python代码里面写就是这样:
在这里插入图片描述
我看着都难受。所以砍了,砍了。

okey,那么这个最后的改动就是这个。

项目结构

那么之后的话,来看到我们的这个项目结构
在这里插入图片描述
这个项目结构的的话,一目了然,其实很简单。就这几个部分,

comm

这个部分是定义我们的一些常量,还有这个工具类。
在这里插入图片描述
在这里插入图片描述

errors

之后是异常的包,这个包里面全是我们定义的异常。然后这些异常的话,都是继承到这个类:


from comm.strings import string_with_arrows

class HlangError:
    def __init__(self, pos_start, pos_end, error_name, details):
        self.pos_start = pos_start
        self.pos_end = pos_end
        self.error_name = error_name
        self.details = details


    def as_string(self):
        red_code = "33[91m"
        reset_code = "33[0m"
        result = f'{self.error_name}: {self.details}n'
        result += f'File {self.pos_start.fn}, line {self.pos_start.ln + 1}'
        result += 'nn' + string_with_arrows(self.pos_start.ftxt, self.pos_start, self.pos_end)
        return red_code + result + reset_code


core

最后就是我们的核心包,这里面就是我们的词法解析器,语法解析器,解释器的实现了。
然后看的话从对应的抽象类(基类)里面看:
在这里插入图片描述

然后的话,在这个文件里面:
在这里插入图片描述
是我们的这个解释器的具体实现部分,还有常量等等的定义部分,后面的这个shell文件直接调用这个。

项目打包

那么这里的话,我们的项目地址是:gitee.com/Huterox/hla…

然后项目的话当然已经打包好了,在这里就可以下载:
在这里插入图片描述

Pyinstaller

那么这里的话,也是使用到Pyinstaller进行打包。所以的话,需要下载

pip install pyinstaller

即可完成下载。

编写Spec文件

由于这个包含的模块比较多,所以的话,我们需要这个编写这个文件。
这里的话我直接贴出来代码:

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None


a = Analysis(['hlang_shell.py'],
             pathex=['C:/Users/31395/Desktop/Hlang'],
             binaries=[],
             datas=[
                ('C:/Users/31395/Desktop/Hlang/comm/*', 'comm'),
                ('C:/Users/31395/Desktop/Hlang/errors/*', 'errors'),
                ('C:/Users/31395/Desktop/Hlang/core/*', 'core')
             ],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='Hlang',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=True , icon='favicon.ico')
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               upx_exclude=[],
               name='Hlang')

  • pathex: 设置脚本所在的路径,可以是单个路径或者路径列表。
  • datas: 指定需要打包到可执行文件中的其他非 Python 文件,可以是单个文件或者文件夹,并指定在可执行文件内的相对路径。
  • hiddenimports: 设置需要隐式导入的模块,即无法通过静态分析检测到的依赖模块。
  • cipher: 设置加密算法,目前该参数为 None,表示不进行加密。
  • exclude_binaries: 设置是否排除二进制文件。
  • name: 指定生成的可执行文件的名称。
  • debug: 设置是否开启调试模式。
  • bootloader_ignore_signals: 设置引导加载程序是否忽略信号。
  • strip: 设置是否删除调试符号。
  • upx: 设置是否使用 UPX 压缩可执行文件。
  • console: 设置是否为控制台应用程序,如果为 False,则为窗口应用程序。
  • icon: 指定可执行文件的图标文件。

在这里插入图片描述

之后执行

pyinstaller hlang.spec

这里的话,注意创建好虚拟环境,这样的话,打包的程序更干净,体积更小。 我这里是直接使用pycharm 创建了。当然你也可以使用conda或者virtual。

总结

那么到这里的话,这个家伙就算搞完了。接下来继续数学强化,还差几个小结。然后的话,就轻松一点了,这个时候就只需要巩固,刷真题即可。

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论