在上一篇文章中,我们搭好了一个编程语言解释器基本的框架,完成了一部分的词法分析器,下面让我们继续努力。用Python开发一个自制的编程语言(虚拟机解释型)[1] 词法分析器(1)_嘉定世外的JinJiayang的博客-CSDN博客

目标分析

我们的解释器能解析字符串(双引号包围的字符),数字,标识符(由字母、数字和下划线组成,可以与关键字重名),符号(在上一集提到),操作符(在上一集提到)。

具体实现

step1 搭好大致框架

class WordParser:...def parse(self):token = ''line = 0result = []small_result = {"value": []}fg = False

这段代码的含义是什么呢?

在WordParser类内部声明了parse(分析)方法,里面又定义了五个变量:

  • token:当前分析的临时结果。
  • line:当前分析是第几行。
  • result:返回值。
  • small_result:存储了每一行的信息,会被放在result里面。
  • fg:标志当前是否处于字符串的内部。

然后让我们开始编写parse方法。

step2 主循环

这个很简单:

        for char in self._string:...if token != "":small_result["value"].append(token)if len(small_result["value"]) > 0:small_result["line"] = linesmall_result["string"] = self._string.split()[-1]result.append(small_result)return result

char就是当前需要分析的字符,在遍历结束后,有可能token和small_result不为空,因此我们需要将它们放进result中,最后方法结束,返回result。

step3 行保存

我们的编程语言以换行符为结束标志,而不是分号,因此在每一行结束后都需要将small_result放入result。

            if char == "\n":if token is not '':small_result["value"].append(token)token = ''line += 1if len(small_result["value"]) > 0:small_result["string"] = self._string.split("\n")[line - 1]small_result["line"] = lineresult.append(small_result)small_result = {"value": []}

step4 分析字符

step4.1 分析字符串

            if char == '"':fg = not fgif not fg:small_result["value"].append(token)token = ''small_result["value"].append(char)elif fg:token += char

step4.2 分析空格(保存token)

            elif self.is_space(char):if token is not '':small_result["value"].append(token)token = ''

step4.3 分析数字

            elif self.is_digit(char) and (len(token) == 0 or token.isdigit()):token += charelif self.is_digit(char):for tk in token:if not (self.is_letter(tk) or self.is_digit(tk)):small_result["value"].append(token)token = ""breaktoken += char

step4.4 分析操作符

            elif not (self.is_digit(char) or self.is_letter(char)):for tk in token:if self.is_letter(tk) or self.is_digit(tk):small_result["value"].append(token)token = ""breaktoken += char

step4.5 分析符号

            elif char in self.symbols:if token != "":small_result["value"].append(token)token = ""small_result["value"].append(char)

注意,符号分析必须单独写,不可以和操作符(operator)混为一谈。

否则"()"将会解析成"()"合在一起,而不是我们希望的"("和")"。

step4.6 分析标识符

            elif self.is_letter(char):if not self.is_var(token):small_result["value"].append(token)token = ''token += char

测试

下面我们给它来一段测试代码:

if __name__ == '__main__':code = """
include sjstd
for(var i=1; i<=100; i=i+1) {sjio <- 1+2 <- ","sjio <- "world" <- _e
}
"""string_list = WordParser(code).parse()for i in string_list:print(i)

结果:

{'value': ['include', 'sjstd'], 'string': 'include sjstd', 'line': 2}
{'value': ['for', '(', 'var', 'i', '=', '1', ';', 'i', '<=', '100', ';', 'i', '=', 'i', '+', '1', ')', '{'], 'string': 'for(var i=1; i<=100; i=i+1) {', 'line': 3}
{'value': ['sjio', '<-', '1', '+', '2', '<-', '"', ',', '"'], 'string': '    sjio <- 1+2 <- ","', 'line': 4}
{'value': ['sjio', '<-', '"', 'world', '"', '<-', '_e'], 'string': '    sjio <- "world" <- _e', 'line': 5}
{'value': ['}'], 'string': '}', 'line': 6}

至此,我们的词法分析器构造完成。

最终完整代码

class WordParser:def __init__(self, s):self._string = sself.operators = ['+', '*', '-', '/', '%', "//",'=','>', '<', '>=', '==', '<=', '!=','<-', '->','.', ',','&', '|','++', '--','&&', '||', '!',"::", ":"]self.symbols = ['(', ')', '"', '{', '}', '[', ']', ',', ';']is_letter = staticmethod(lambda char: ('a' <= char <= 'z') or ('A' <= char <= 'Z') or (char == "_"))is_digit = staticmethod(lambda char: '9' >= char >= '0')is_space = staticmethod(lambda char: True if char == ' ' or char == '\t' else False)is_var = lambda self, char: __import__("functools").reduce(lambda x, y: x and y,[self.is_digit(i) or self.is_letter(i) for i in char],True)def parse(self):token = ''line = 0result = []small_result = {"value": []}fg = Falsefor char in self._string:if char == '"':fg = not fgif not fg:small_result["value"].append(token)token = ''small_result["value"].append(char)elif fg:token += charelif char == "\n":if token is not '':small_result["value"].append(token)token = ''line += 1if len(small_result["value"]) > 0:small_result["string"] = self._string.split("\n")[line - 1]small_result["line"] = lineresult.append(small_result)small_result = {"value": []}elif self.is_space(char):if token is not '':small_result["value"].append(token)token = ''elif char in self.symbols:if token != "":small_result["value"].append(token)token = ""small_result["value"].append(char)elif self.is_digit(char) and (len(token) == 0 or token.isdigit()):token += charelif self.is_digit(char):for tk in token:if not (self.is_letter(tk) or self.is_digit(tk)):small_result["value"].append(token)token = ""breaktoken += charelif self.is_letter(char):if not self.is_var(token):small_result["value"].append(token)token = ''token += charelif not (self.is_digit(char) or self.is_letter(char)):for tk in token:if self.is_letter(tk) or self.is_digit(tk):small_result["value"].append(token)token = ""breaktoken += charif token != "":small_result["value"].append(token)if len(small_result["value"]) > 0:small_result["line"] = linesmall_result["string"] = self._string.split()[-1]result.append(small_result)return result

END

好了,今天到此为止,下一篇我们将详细讲述如何根据符号流解析AST树,保证让你拥有一个属于自己的parser。

如果你也想尝试这个项目的话,创作不易,不妨点个赞,关注本专栏,thanks~

用Python开发一个自制的编程语言(虚拟机解释型)[2] 词法分析器(2)相关推荐

  1. [python] 开发一个跟随角色移动的地图游戏demo

    用python开发一个2D角色游戏的地图Demo 如今很多大学生大学学习了编程语言,想做游戏却迟迟做不出一个游戏雏形来,接下来就和大家谈论下游戏中地图移动的简单原理并用python这一门非常火的语言进 ...

  2. 国外大牛教你,如何用Python开发一个简单的区块链数据结构| 建议收藏

    来源 | Medium 作者 | arjuna sky kok 整理 / Aholiab 出品 | 区块链大本营(blockchain_camp) 根据IEEE此前的一项调查,Python已成为最受开 ...

  3. 用python实现todolist_So easy !用 Python 开发一个todolist

    原标题:So easy !用 Python 开发一个todolist 有一句话是这样说的:"凡事预则立,不预则废",说的是我们在做事之前,最好制定好你的计划,然后有序的去执行,这样 ...

  4. Python开发一个股票类库

    前言 使用Python开发一个股票项目.  项目地址:  https://github.com/pythonstock/stock  相关资料:  http://blog.csdn.net/freew ...

  5. python开发的著名软件公司_软件开发公司_软件外包_项目外包平台基于Python开发一个全文检索系统...

    基于Python开发一个全文检索系统.功能要求为: 使用全文检索引擎对文本进行检索.文本的格式为Word.PDF.TXT. 同时按数据域进行复合条件检索.数据域指文本对应的信息,例如创建人.文件编号. ...

  6. 文案生成 python_用 Python 开发一个【视频营销号】生成器

    原标题:用 Python 开发一个[视频营销号]生成器 之前小帅b在网上看到一个营销号文案生成器,把我给乐的: 其实这个用 Python 实现非常简单,根据用户输入的内容,简单替换一下关键字就可以了, ...

  7. Python开发一个滑雪小游戏

    擅长领域:Python开发一个小游戏 今日重点:一步步分析and越过亚马逊的反爬虫机制 一.如何搭建开发环境环境 一起来学pygame吧 游戏开发30例(开篇词)--环境搭建+游戏效果展示 windo ...

  8. 从0到1使用python开发一个半自动答题小程序

    从0到1使用python开发一个半自动答题小程序 前言 最近每天都有玩微信读书上面的每日一答的答题游戏,完全答对12题后,可以瓜分无限阅读卡.但是从小就不太爱看书的我,很难连续答对12道题,由此,产生 ...

  9. Python开发一个短网址生成器

    Python开发一个短网址生成器 原理简述: 生成短网址: 首先,将长网址插入mysql一个表中,此时生成一个主键id,将主键id 做base62编码 为一个短标识,这个短标识拼接域名即为短网址. 短 ...

最新文章

  1. B站学强化学习?港中文周博磊变身up主,中文课程已上线
  2. [HTML/CSS]colum-gap属性
  3. 【实用】MB52库存报表转网格格式
  4. 记一次关于mock Systemc.currentTimeMillis的实践
  5. Python学习笔记:利用Pyforest导入本地已安装的库
  6. python判断字符串,str函数isdigit、isdecimal、isnumeric的区别
  7. JavaScript中的“ new”关键字是什么?
  8. mysql查找配置文件的顺序
  9. oracle 表收缩,Oracle 收缩表大小 Oracle Shrink Table
  10. shiro自定义logout filter
  11. NoiseAsh Rule Tec All Collection for Mac(无源均衡器)
  12. 面试官:“你为什么离开上家公司?”怎么回答?
  13. SQL Prompt数据库教程:标量用户定义函数误用作常量
  14. 求矩阵中非零元素个数(L0范式)
  15. 优秀的 Node.js 包汇总
  16. D. Rescue Nibel(cf) 区间覆盖 + 组合数学
  17. 艺赛旗(RPA)isrpa7.0 的 IE 自动 pagedown 到我们需要操作的地方
  18. 小程序篇1-1:搜索框输入关键字、词检索;点击取消恢复默认状态
  19. 《数据库》数据库的备份与恢复
  20. 警惕安全档案的陷阱 | 确认偏见

热门文章

  1. HTML中的form表单及其提交原理
  2. TryHackMe新手村
  3. 如何查看本机中的ODBC数据源
  4. Python:航空公司客户价值分析实战
  5. 铁三2018.5.5数据分析
  6. 超级通俗易懂的奇异值分解(SVD)讲解
  7. 有什么好用的提词器工具?这四个提词器告别演讲烦恼
  8. 小红书数据分析:首播卖6亿,小红书直播开启新纪元!
  9. python print输出省略号
  10. 那些藏在wordpress中的工具