文档章节

Lua1.1 语法分析

晓寒
 晓寒
发布于 2014/09/13 23:52
字数 890
阅读 467
收藏 0

无论是 lua_dostring 或者是 lua_dofile,都调用了语法分析 lua_parse。
在 lua 里面语法分析器是用 yacc 生成的,就是y.tab.c 文件,lua.stx 就是 yacc 的输入文件。
这里说的东西基本上编译原理书里都有介绍,如需要进一步了解,请自行参阅。

在说语法分析之前,说下词法分析。
lua 的词法分析是手写的,手写的词法分析性能比较好,这个在 lua1.1 自带的文档里有说明,
文件名 lua.ps, 第 8 页 (或者 www.lua.org/semish94.html 的 Implementation 节 )
,手写的词法分析器性能提高了 2 倍。
(文件内部的标题为 :The design and implementation of a language for extending applications)。

词法分析的输入就是从 lua_setinput 过来的那个 Input 函数指针。
一些保留字做特殊处理,reserved 数组里存在着所有的保留字。
词法分析的主要函数为 yylex,它由语法分析调用,每次返回一个 token。它内部实现是一个大的 switch case。注意,当 token 的类型为 NAME 时,它要先调用方法 findReserved 检查一下其是否是保留字,如果是的话, 直接返回保留字 token。
token 分为两种,一种只有类型,一种有值和类型。
如果 token 的类型够以描述它自己的话,就不需要值,比如保留字,比较运算符,只有类型便足以识别它自己。
而像数值型就需要值,比方一个数为 789,词法分析会这样返回它:返回一个 NUMBER,它的值为 789。至于语法分析怎么用,是语法分析自己的事。
可以参考它的 Lex 输入文件(虽然该输入文件在 Lua1.1 里没有使用),就是在 src/yacc 目录里的 lua.lex。更容易看出 lex.c 里的那个 swith case 为什么要那样写。

接下来看下语法分析 lua_parse :
y.tab.c 文件

/*
** Parse LUA code and execute global statement.
** Return 0 on success or 1 on error.
*/
int lua_parse (void)
{
 Byte *init = initcode = (Byte *) calloc(GAPCODE, sizeof(Byte));
 maincode = 0; 
 maxmain = GAPCODE;
 if (init == NULL)
 {
  lua_error("not enough memory");
  return 1;
 }
 err = 0;
 if (yyparse () || (err==1)) return 1;
 initcode[maincode++] = HALT;
 init = initcode;
#if LISTING
 PrintCode(init,init+maincode);
#endif
 if (lua_execute (init)) return 1;
 free(init);
 return 0;
}

可以看到在语法分析 yyparse (这个就是由 yacc 生成的语法分析器的入口)之后,调用虚拟机执行指令 lua_execute。

PrintCode 打印字节码,它由 LISTING 宏控制。如果要打印字节码,需要保证 PrintCode 被正常的调用。具体修改请参见打印字节码那篇。

因为这里是由 yacc 生成的,关于 yacc 的内容不是我关注的重点,不再详细说明,感兴趣的可以自行查找相关资料。

我比较喜欢那个从 lua3.1 版本开始的手写的递归下降语法分析,有可能的话到那时再分析下语法分析过程吧。

虽然说 lua1.1 是栈式虚拟机,但是,从他生成的指令却不能保存下来直接使用,而必须从源代码解析后直接生成。可以认为它里面没有编译这一步,一边解释一边执行。到版本 Lua2.4 才可以保存生成的指令,有了独立的编译器,数据和代码的全部信息都保存到编译生成的字节码里。

语法分析的结果是一个字节码指令数组,也就是之前我们看到的字节码展示。
到此,字节码已经生成,编译器前端的工作算是做完了。

© 著作权归作者所有

晓寒
粉丝 35
博文 119
码字总数 133745
作品 0
海淀
私信 提问
Lua1.1 公开发布的第一版

Lua1.1 是官方公开发布的第一版,是事实上的第一版 ,也是最早发布的一版。 代码从这里 www.lua.org/ftp/lua-1.1.tar.gz 下载,事实上在 www.lua.org/versions.html 页面,有所有的可以下下载...

晓寒
2014/09/02
333
1
Lua1.0 代码分析 opcode.c

opcode.c 代码分析 Lua1.0 虚拟机的实现,语法分析中生成的字节码交给它 luaexecute 来执行。 这个文件的主要部分就是 luaexecute 函数,而它就是很大的 switch case,Lua1.0 中定义的字节码...

晓寒
2014/08/31
472
0
Lua1.1 虚拟机指令分析(一)

在语法分析 luaparse 之后,调用 luaexecute 来执行语法分析生成的字节码。 虚拟机的指令是一个枚举型,就是在 opcode.h 中的 OpCode, 通过 lua_execute 中的那个 switch case 来看下指令对应...

晓寒
2014/09/14
731
0
Lua1.1 Lua 的参考手册 (一)

说明: 这个文档是 Lua1.1 的 doc 目录里的 manual.ps 文件。 原文版权归原作者所有,这篇翻译只是作为学习之用。如果翻译有不当之处,请参考原文。 -------------------以下是正文---------...

晓寒
2014/09/04
196
0
Lua1.1 Lua 的设计和实现 (二)

(接上篇) -------------------------------------- 实现 -------------------------------------- 扩展语言总是由应用程序以某种方式解释执行的。简单的扩展语言可以直接从源代码进行解释执...

晓寒
2014/09/03
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

nginx学习笔记

中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯。 是连接两个独立应用程序或独立系统的软件。 web请求通过中间件可以直接调用操作系统,也可以经过中间件把请求分发到多...

码农实战
48分钟前
5
0
Spring Security 实战干货:玩转自定义登录

1. 前言 前面的关于 Spring Security 相关的文章只是一个预热。为了接下来更好的实战,如果你错过了请从 Spring Security 实战系列 开始。安全访问的第一步就是认证(Authentication),认证...

码农小胖哥
今天
8
0
JAVA 实现雪花算法生成唯一订单号工具类

import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;import java.util.Calendar;/** * Default distributed primary key generator. * * <p> * Use snowflake......

huangkejie
昨天
11
0
PhotoShop 色调:RGB/CMYK 颜色模式

一·、 RGB : 三原色:红绿蓝 1.通道:通道中的红绿蓝通道分别对应的是红绿蓝三种原色(RGB)的显示范围 1.差值模式能模拟三种原色叠加之后的效果 2.添加-颜色曲线:调整图像RGB颜色----R色增强...

东方墨天
昨天
10
1
将博客搬至CSDN

将博客搬至CSDN

算法与编程之美
昨天
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部