一、词法分析

词法分析(英语:lexical analysis)是计算机科学中将字符序列转换为单词(Token)序列的过程。进行词法分析的程序或者函数叫作词法分析器(Lexical analyzer,简称Lexer),也叫扫描器(Scanner)。词法分析器一般以函数的形式存在,供语法分析器调用。

二、Lua词法分析器

首先需要读取Lua文件中的内容,然后逐字符读取进行判断组合成一个一个的单词。判断单词就需要了解Lua语言中的数据类型,具体如下:

1. 变量标识符

  • 单个字符 例如a = 1中的“a”
  • 多个字符 例如 player
  • 下划线开头 例如 _key
  • 字符和数字组合  例如 key123_key23 

    2. 数字

  • 整数 例如 12302021
  • 小数    例如 3.1415926.41
  • 十六进制  例如 0x00440XFF1A0xab12
  • 科学计数法 例如 2e-20.2e+1

    3. 字符串

  • 双引号 "Hello Lua"
  • 单引号 'abcd'
  • 双中括号(多行) [[xxzz]]

    4. 关键字

本质上可以和标识符合并,然后读取出来后再进行匹配。

    5. 操作符号

  • 算术运算 +-*/%
  • 比较运算 ><==>=<=
  • 赋值运算 “=”
  • 位运算
  • 字符串连接符  “..”

    6. 注释

  • 单行注释  以 “--”开始 到 行末
  • 多行注释 “--[[”  开始 到 “]]” 结束

大体了解了Lua语言的组成后,就可以开始编写词法分析程序了,下面展示了部分代码用于说明整个词法分析的过程。

1) 首先需要写字符的处理方法。

get_char 用于从字符流中取出下一个字符;

peek_char 返回下一个字符但不从字符流中取出;

put_char 将取出的字符放回去。

 1 def get_char(self):
2 """ 取出下1个字符 """
3 if self._Index + 1 < self._FileSize:
4 self._Index += 1
5 return self._StreamBuff[self._Index]
6 else:
7 return None
8 def peek_char(self):
9 """ 获取下1个字符,但不取出 """
10 if self._Index + 1 < self._FileSize:
11 return self._StreamBuff[self._Index + 1]
12 return None
13 def put_char(self):
14 """ 回退获取的字符 """
15 if self._Index > -1:
16 self._Index -= 1

   2) 识别并组成一个Token单词。

循环获取字符,并进行逐个条件判断,最终形成一个单词(Token)。需要注意数字和字符的组合、减号、小数点等的判断。

 1 def parse_read_token(self):
2 c = self.get_char()
3 token_str = ""
4 token_type = TokenType.L_EOF
5 while c is not None:
6 if c in TokenType.SkipWords:
7 c = self.get_char()
8 continue
9 elif c.isdigit(): # ....
10 elif c.isalpha() or c == '_':
11 elif c == '.': # ....
12 elif c == '\"' or c == "\'": # 字符串
13 elif c == '[': # 区分[ 和 [[
14 elif c == '{': # ....
15 elif c == '(': # ....
16 elif c == ']': # ....
17 elif c == '}': # ....
18 elif c == ')': # ....
19 elif c in TokenType.Operators: # ....
20 else: # error
21 c = self.get_char()
22 return Token(token_type, token_str) 

3)循环读取全部的Token直到文件字符数据流结尾。

 1 def parse(self):
2 while True:
3 token = self.parse_read_token()
4 if token.tokenType == TokenType.L_ERROR:
5 return False
6 elif token.tokenType == TokenType.L_EOF:
7 break
8 elif token.tokenType != TokenType.L_COMMENT:
9 self.mTokens.append(token)
10 return True

三、总结

通过上面的几步就可以完成对Lua文件中的字符流进行分析,然后组成Token流。Token流将会是语法分析的输入内容。以上就是Lua词法分析的内容,写完分析程序后还需要多调试,使用不同风格编写的Lua代码文件进行测试。

文章来自我的公众号,大家如果有兴趣可以关注,具体扫描关注下图。

【Lua篇】静态代码扫描分析(二)词法分析的更多相关文章

  1. 【Lua篇】静态代码扫描分析(一)初步介绍

    一.静态代码分析         静态代码分析是一种通过检查代码而不是执行程序来发现源代码中错误的手段.通常可以帮助我们发现常见的编码错误,例如: 语法错误 违反制定的标准编码 未定义的变量 安全性问 ...

  2. 【Lua篇】静态代码扫描分析(三)语法分析

    一.语法分析 通过将词法分析获取的Token流按照目标语言的语法进行解析的过程,例如解析函数声明.函数调用.变量声明.各种语句等. 二.Lua语法分析 在写语法分析程序前,先需要了解Lua的语句和语法 ...

  3. 【Lua篇】静态代码扫描分析(四)规则检查

    一.前言 通过前面三篇文章已经初步实现了将Lua源代码文件读取解析成语法树,现在就可以通过得到的语法树进行指定规则的代码扫描检查.下图简单列举了一下单个Lua文件内部的语法关系情况(注意并非真正的类图 ...

  4. 静态代码扫描工具PMD定制xml的规则(一)操作篇

    0.前言 PMD作为开源的静态代码扫描工具有很强的扩展能力,可使用java或xpath定制rule.第一篇从操作上讲解如何定制一个用于扫描xml是否规范的规则.首先我们知道xml格式的文件在java工 ...

  5. DEVOPS技术实践_05:sonar静态代码扫描

    一.SonarQube静态代码扫描平台 1.1 安装 https://www.sonarqube.org/官网 1.2 下载软件包 https://www.sonarqube.org/download ...

  6. 使用OClint进行iOS项目的静态代码扫描

    使用OClint进行iOS项目的静态代码扫描 原文链接:http://blog.yourtion.com/static-code-analysis-ios-using-oclint.html 最近需要 ...

  7. Lint——Android SDK提供的静态代码扫描工具

    Lint和FindBugs一样,都是静态代码扫描工具,区别在于它是Android SDK提供的,会检查Android项目源文件的正确性.安全性.性能.可用性等潜在的bug并优化改进. 下图简单地描述了 ...

  8. Objective C静态代码扫描和代码质量管理 OClint + SonarQube

    OClint是针对C, C++及Objective C代码的静态扫描分析工具,而SonarQube是一个开源的代码质量管理平台.本文将实现将OClint的扫描结果导入到SonarQube中,已实现对O ...

  9. Java提高篇——静态代码块、构造代码块、构造函数以及Java类初始化顺序

    静态代码块:用staitc声明,jvm加载类时执行,仅执行一次构造代码块:类中直接用{}定义,每一次创建对象时执行.执行顺序优先级:静态块,main(),构造块,构造方法. 构造函数 public H ...

随机推荐

  1. MySQL数据库企业集群项目实战(阶段三)

                              MySQL数据库企业集群项目实战(阶段三) 作者 刘畅 时间 2020-10-25 目录 1 架构拓扑图 1 1.1 方案一 1 1.2 方案二 2 ...

  2. JNI小记

    本文参考<较详细的介绍JNI>一文,并添加了一些方法,代码已经过测试,留待日后工作使用.关于JNI的HelloWorld的例子,就不赘述了. java代码: 1 package com.c ...

  3. PHP解决并发问题的几种实现(转)

      对于商品抢购等并发场景下,可能会出现超卖的现象,这时就需要解决并发所带来的这些问题了 在PHP语言中并没有原生的提供并发的解决方案,因此就需要借助其他方式来实现并发控制. 方案一:使用文件锁排它锁 ...

  4. Linux | 搜索命令

    grep grep 命令用于在文本中执行关键词搜索,并显示匹配的结果,格式:grep[选项][文本] grep命令的参数及其作用 参数 作用 -b 将可执行文件当作文本文件对待 -c 公显示找到的行数 ...

  5. YAOI Round #1 题解

    前言 比赛网址:http://47.110.12.131:9016/contest/3 总体来说,这次比赛是有一定区分度的, \(\text{ACM}\) 赛制也挺有意思的. 题解 A. 云之彼端,约 ...

  6. 答读者问(1):非模式物种找marker;如何根据marker定义细胞类型

    下午花了两个小时回答读者的疑问,觉得可以记录下来,也许能帮到一部分人. 第一位读者做的是非模式物种的单细胞. 一开始以为是想问我非模式物种的marker基因在哪儿找,读者朋友也提到了blast 研究的 ...

  7. maven添加阿里云镜像

    apache的maven服务器国内访问太慢了,用阿里的镜像会好很多. 1.maven的配置文件有两个,安装目录conf文件夹下settings.xml和用户目录.m2文件夹下的settings.xml ...

  8. 【剑指offer】05. 替换空格

    剑指 Offer 05. 替换空格 知识点:: 题目描述 请实现一个函数,把字符串 s 中的每个空格替换成"%20". 示例 输入:s = "We are happy.& ...

  9. UI自动化学习笔记- PO模型介绍和使用

    一.PO模型 1.PO介绍:page(页面) object(对象) 在自动化中,Selenium 自动化测试中有一个名字经常被提及 PageObject (思想与面向对象的特征相同),通常PO 模型可 ...

  10. 关于GPIO口的一些概念性问题

    一.什么是GPIO? GPIO的英文全称是General-Purpose IO ports,也就是通用输入输出口. 在嵌入式系统中,经常需要控制许多结构简单的外部设备或者电路,这些设备有的需要通过CP ...