Lua 作为数据描述语言使用完整示例

我们看两个完整的例子来阐明 Lua 语言的使用。
第一个例子来自于 Lua 网站,他展示了 Lua 作为数据描述语言的使用。
第二个例子讲解了马尔可夫链算法的实现,这个算法在 Kernighan & Pike 著作的 Practice of Programming 书中也有描述。这两个完整的例子之后,Lua 语言方面的介绍便到此结束。后面将继续介绍 table 和面向对象的内容以及标准库、C-API 等。

Lua 作为数据描述语言使用

Lua 网站保留一个包含世界各地使用 Lua 创建的工程的例子的数据库。在数据库中我们用一个构造器以自动归档的方式表示每一个工程入口点,代码如下:

entry{ 
title = "Tecgraf", 
org = "Computer Graphics Technology Group, PUC-Rio", 
url = "http://www.tecgraf.puc-rio.br/", 
contact = "Waldemar Celes", 
description = [[ 
TeCGraf is the result of a partnership between PUC-Rio, the Pontifical Catholic University of Rio de Janeiro, and <A HREF="http://www.petrobras.com.br/">PETROBRAS</A>, the Brazilian Oil Company. TeCGraf is Lua's birthplace, and the language has been used there since 1993. Currently, more than thirty programmers in TeCGraf use Lua regularly; they have written more than two hundred thousand lines of code, distributed among dozens of final products.]] 
} 

有趣的是,工程入口的列表是存放在一个 Lua 文件中的,每个工程入口以 table 的形式作为参数去调用 entry 函数。我们的目的是写一个程序将这些数据以 html 格式展示出来。由于工程太多,我们首先列出工程的标题,然后显示每个工程的明细。结果如下:

<HTML> 
<HEAD><TITLE>Projects using Lua</TITLE></HEAD> 
<BODY BGCOLOR="#FFFFFF"> 
Here are brief descriptions of some projects around the world that use <A HREF="home.html">Lua</A>. 
<UL> 
<LI><A HREF="#1">TeCGraf</A> 
<LI> ... 
</UL> 
<H3> 
<A NAME="1" 
 HREF="http://www.tecgraf.puc-rio.br/">TeCGraf</A> 
<SMALL><EM>Computer Graphics Technology Group, 
PUC-Rio</EM></SMALL> 
</H3> 
TeCGraf is the result of a partnership between 
... 
distributed among dozens of final products.<P> 
Contact: Waldemar Celes 
<A NAME="2"></A><HR> 
... 
</BODY></HTML> 

为了读取数据,我们需要做的是正确的定义函数 entry,然后使用 dofile 直接运行数据文件即可(db.lua)。注意,我们需要遍历入口列表两次,第一次为了获取标题,第二次为了获取每个工程的表述。一种方法是:使用相同的 entry 函数运行数据文件一次将所有的入口放在一个数组内;另一种方法:使用不同的 entry 函数运行数据文件两次。因为 Lua 编译文件是很快的,这里我们选用第二种方法。

首先,我们定义一个辅助函数用来格式化文本的输出(参见 5.2 函数部分内容)

function fwrite (fmt, ...) 
return io.write(string.format(fmt, unpack(arg))) 
end 
第二,我们定义一个 BEGIN 函数用来写 html 页面的头部 
 
function BEGIN() 
io.write([[ 
<HTML> 
<HEAD><TITLE>Projects using Lua</TITLE></HEAD> 
<BODY BGCOLOR="#FFFFFF"> 
Here are brief descriptions of some projects around the 
world that use <A HREF="home.html">Lua</A>. 
]]) 
end 
第三,定义 entry 函数
a. 第一个entry函数,将每个工程一列表方式写出,entry的参数o是描述工程的table。
function entry0 (o) 
 N=N + 1 
local title = o.title or '(no title)'
 fwrite('<LI><A HREF="#%d">%s</A>\n', N, title) 
end 
如果 o.title 为 nil 表明 table 中的域 title 没有提供,我们用固定的"no title"替换。b. 第二个 entry 函数,写出工程所有的相关信息,稍微有些复杂,因为所有项都是可选的。
function entry1 (o) 
 N=N + 1 
local title = o.title or o.org or 'org'
 fwrite('<HR>\n<H3>\n') 
local href = ''
 if o.url then 
 href = string.format(' HREF="%s"', o.url) 
 end 
 fwrite('<A NAME="%d"%s>%s</A>\n', N, href, title) 
 if o.title and o.org then 
 fwrite('\n<SMALL><EM>%s</EM></SMALL>', o.org) 
 end 
 fwrite('\n</H3>\n') 
 if o.description then 
 fwrite('%s', string.gsub(o.description, 
 '\n\n\n*', '<P>\n')) 
 fwrite('<P>\n') 
 end 
 if o.email then 
 fwrite('Contact: <A HREF="mailto:%s">%s</A>\n', 
 o.email, o.contact or o.email) 
 elseif o.contact then 
 fwrite('Contact: %s\n', o.contact) 
 end 
end 
由于 html 中使用双引号,为了避免冲突我们这里使用单引号表示串。
第四,定义 END 函数,写 html 的尾部
function END() 
fwrite('</BODY></HTML>\n') 
end 
在主程序中,我们首先使用第一个 entry 运行数据文件输出工程名称的列表,然后再以第二个 entry 运行数据文件输出工程相关信息。
BEGIN() 
N = 0 
entry = entry0 
fwrite('<UL>\n') 
dofile('db.lua') 
fwrite('</UL>\n') 
N = 0 
entry = entry1 
dofile('db.lua') 
END()
发布了257 篇原创文章 · 获赞 152 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_39885372/article/details/104349625