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

一、语法分析
通过将词法分析获取的Token流按照目标语言的语法进行解析的过程,例如解析函数声明、函数调用、变量声明、各种语句等。
二、Lua语法分析
在写语法分析程序前,先需要了解Lua的语句和语法,然后进行逐个解析。
下面简单列举一下Lua的语句:
1. 函数定义
1 -- 普通的函数声明
2 function demo1()
3 -- <函数体>
4 end
5 -- 类方法
6 function t.demo2(self)
7 -- <函数体>
8 end
9 -- 方法调用中的匿名函数(其实还有很多)
10 some_method_call(arg1, function() <callback> end)
2. 函数调用
1 -- 普通的函数调用
2 print("Hello Lua")
3 -- 模块方法
4 math.random(1,2)
5 -- 类方法
6 obj:set_id(xx)
3. 赋值语句
1 -- 带local局部变量声明赋值
2 local a = 1
3 -- 多变量
4 local a,b,c = 2,3
5 -- 全局的变量
6 g_a = 3
7 -- 赋值可以是函数、函数调用、表等
8 g_c,g_b = {}, function() end
4. 条件分支
1 -- if条件分支
2 if a > 1 then
3 elseif a > 2 then
4 else
5 end
5. for循环
1 -- for循环
2 for i=1,10,2 do
3 end
6. for迭代器
1 -- 迭代包含in pairs 和 in ipairs
2 for k,v in pairs(tb) do
3 end
7. while循环
1 -- while循环,条件可以很复杂
2 while a >1 and b > 1 do
3 end
8. repeat until 循环
1 repeat
2 until a > 1
上面仅仅简单了进行了举例,实际上项目中的写法是千奇百怪的,因此需要确保包含所有的语法规则。在进行语法解析的时候,首先进行代码块的解析,可以把一个文件看作整个代码块,里面包含各种的语句。然后其实是逐语句解析,先取出一个Token,判断这个Token的类型,然后决定更细规则的解析,就像下面代码列举的过程一样。
1. 语法解析的入口,调用block解析。
1 def parse(self):
2 self._TokenNum = self.mTokens
3 block = self.on_block_parse()
4 return block
2. 对block解析的时候,实际是循环调用逐语句解析,直到匹配到语句块结束标记。
1 def on_block_parse(self):
2 token = self.get_token()
3 statements = []
4 while token is not None:
5 # until,else,elseif,end
6 if self.is_end_token(token):
7 self.put_token()
8 break
9 # 语句解析
10 statement = self.on_statement_parse(token)
11 if not statement:
12 break
13 statements.append(statement)
14 token = self.get_token()
15 return Block(statements)
3. 逐语句解析就是获取Token的类型,并调用对应类型的解析方法。
1 def on_statement_parse(self, token):
2 # 函数
3 if token.tokenType == T.FUNCTION:
4 return self.on_function_parse(token)
5 # for .. in .. do .. end
6 elif token.tokenType == T.FOR:
7 return self.on_for_parse(token)
8 # while .. do .. end
9 elif token.tokenType == T.WHILE:
10 return self.on_while_parse(token)
11 # repeat ... until xx
12 elif token.tokenType == T.REPEAT:
13 return self.on_repeat_parse(token)
14 # if .. elseif ... else .. end
15 elif token.tokenType == T.IF:
16 return self.on_if_parse(token)
17 # do ... end
18 elif token.tokenType == T.DO:
19 return self.on_do_parse(token)
20 # local xx
21 elif token.tokenType == T.LOCAL:
22 return self.on_local_parse(token)
23 # return xxx
24 elif token.tokenType == T.RETURN:
25 return self.on_return_parse(token)
26 else:
27 return self.on_expression_parse(token)
4. 列举一下while循环的解析,其中会调用表达式解析while的条件,调用block解析while的语句体,然后检查是否有end。基本上其他的语句也是按照这样的方式进行分析与解析。
1 def on_while_parse(self, token):
2 """ while 循环 """
3 # while <condition> do
4 exp = self.on_expression_parse(self.get_token())
5 if not exp:
6 self.print_syntax_error(token)
7 return None
8 next_token = self.get_token()
9 if next_token.text != 'do':
10 self.print_syntax_error(next_token)
11 return
12 body = self.on_block_parse()
13 next_token = self.get_token()
14 if next_token.text != 'end':
15 self.print_syntax_error(next_token)
16 return None
17 while_statement = LNodeWhile(token.lineno, exp, body)
18 return while_statement
三、总结
通过上面的简单介绍,不知可能上手写一写呢?将所有的语句都解析完成后,接下来就是进行静态代码扫描了。如果是使用C或者C++写的话,完全可以从Lua的源码中提取上面的词法和语法解析内容,而直接进行代码规则扫描检查的编写。
文章来自我的公众号,大家如果有兴趣可以关注,具体扫描关注下图。

【Lua篇】静态代码扫描分析(三)语法分析的更多相关文章
- 【Lua篇】静态代码扫描分析(一)初步介绍
一.静态代码分析 静态代码分析是一种通过检查代码而不是执行程序来发现源代码中错误的手段.通常可以帮助我们发现常见的编码错误,例如: 语法错误 违反制定的标准编码 未定义的变量 安全性问 ...
- 【Lua篇】静态代码扫描分析(四)规则检查
一.前言 通过前面三篇文章已经初步实现了将Lua源代码文件读取解析成语法树,现在就可以通过得到的语法树进行指定规则的代码扫描检查.下图简单列举了一下单个Lua文件内部的语法关系情况(注意并非真正的类图 ...
- 【Lua篇】静态代码扫描分析(二)词法分析
一.词法分析 词法分析(英语:lexical analysis)是计算机科学中将字符序列转换为单词(Token)序列的过程.进行词法分析的程序或者函数叫作词法分析器(Lexical analyzer, ...
- 静态代码扫描工具PMD定制xml的规则(一)操作篇
0.前言 PMD作为开源的静态代码扫描工具有很强的扩展能力,可使用java或xpath定制rule.第一篇从操作上讲解如何定制一个用于扫描xml是否规范的规则.首先我们知道xml格式的文件在java工 ...
- DEVOPS技术实践_05:sonar静态代码扫描
一.SonarQube静态代码扫描平台 1.1 安装 https://www.sonarqube.org/官网 1.2 下载软件包 https://www.sonarqube.org/download ...
- 使用OClint进行iOS项目的静态代码扫描
使用OClint进行iOS项目的静态代码扫描 原文链接:http://blog.yourtion.com/static-code-analysis-ios-using-oclint.html 最近需要 ...
- Lint——Android SDK提供的静态代码扫描工具
Lint和FindBugs一样,都是静态代码扫描工具,区别在于它是Android SDK提供的,会检查Android项目源文件的正确性.安全性.性能.可用性等潜在的bug并优化改进. 下图简单地描述了 ...
- Objective C静态代码扫描和代码质量管理 OClint + SonarQube
OClint是针对C, C++及Objective C代码的静态扫描分析工具,而SonarQube是一个开源的代码质量管理平台.本文将实现将OClint的扫描结果导入到SonarQube中,已实现对O ...
- Java提高篇——静态代码块、构造代码块、构造函数以及Java类初始化顺序
静态代码块:用staitc声明,jvm加载类时执行,仅执行一次构造代码块:类中直接用{}定义,每一次创建对象时执行.执行顺序优先级:静态块,main(),构造块,构造方法. 构造函数 public H ...
随机推荐
- 45、screen命令
1.screen命令介绍: 当我们在使用linux远程工具进行远程访问服务器时,进行远程访问的界面往往不能关掉,否则程序将不再运行.而且,程序 在运行的过程中,还必须时刻保证网络的通常,这些条件都很难 ...
- hud 3308 LCIS 线段树 区间合并
题意: Q a b 查询[a, b]区间的最长连续递增子序列的长度 U a b 将下表为a的元素更新为b 区间合并一般都有3个数组:区间最值,左区间最值和右区间最值 具体详见代码 #include & ...
- Docker中容器的备份和恢复(可迁移)
官方文档 备份容器 - save 查看镜像$ docker images 容器快照 - commit$ docker commit CONTAINER xxx/exampleimage-backup: ...
- 排序---python版
冒泡排序: 比较相邻的元素.如果第一个比第二个大,就交换它们两个: 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数: 针对所有的元素重复以上的步骤,除了最 ...
- EF Core3.1 CodeFirst动态自动添加表和字段的描述信息
前言 我又来啦.. 本篇主要记录如何针对CodeFirst做自动添加描述的扩展 为什么要用这个呢.. 因为EF Core3.1 CodeFirst 对于自动添加描述这块 只有少部分的数据库支持.. 然 ...
- ZooKeeper 分布式锁 Curator 源码 01:可重入锁
前言 一般工作中常用的分布式锁,就是基于 Redis 和 ZooKeeper,前面已经介绍完了 Redisson 锁相关的源码,下面一起看看基于 ZooKeeper 的锁.也就是 Curator 这个 ...
- Linux中ftp服务器搭建
一.FTP工作原理 (1)FTP使用端口 [root@localhost ~]# cat /etc/services | grep ftp ftp-data 20/tcp #数据链路:端口20 ftp ...
- CTF-safer-than-rot13-writeup
safer-than-rot13 题目信息 附件: cry100 XMVZGC RGC AMG RVMG HGFGMQYCD VT VWM BYNO, NSVWDS NSGO RAO XG UWFN ...
- [006] - JavaSE面试题(六):泛型
第一期:Java面试 - 100题,梳理各大网站优秀面试题.大家可以跟着我一起来刷刷Java理论知识 [006] - JavaSE面试题(六):泛型 第1问:什么是泛型? Java泛型( generi ...
- [刘阳Java]_为什么要前后端分离
前后端分离已成为互联网项目开发的业界标准使用方式,通过nginx+tomcat的方式(也可以中间加一个nodejs)有效的进行解耦,并且前后端分离会为以后的大型分布式架构.弹性计算架构.微服务架构.多 ...