Lua 语法 |
|
Lua 参考手册的“第 8 章 - Lua 的完整语法”[1] 提供了 Lua 5.1 的扩展 BNF 语法(不包括运算符优先级)。有关优先级,请参见 [第 2.5.6 章 - 优先级]。
这与 Lemon[2] 格式基本相同,只是它允许使用引号字符串作为文字终结符。请参见下面的清单 1。
当然,Lua 的原始 C 解析器存在于 Lua 发行版的源代码中,但它是用 C 手写的,不容易重用。
LpegRecipes 列出了 Lua 中的 Lua 5.1 词法分析器和解析器。
mlp 解析器包含在 MetaLua 中,可以解析 Lua(以及带有语法扩展的 Lua)并将其转换为 AST。mlp 基于 gg 语法生成器,该生成器可以构建具有用户定义语法的可扩展解析器。mlp 和 gg 完全用 Lua 编写,其词法分析器基于 Yueliang(如下)。例如,gg/mlp 用于 MetaLua 和 LuaToCee。
Cheese[3] 是一个使用解析表达式语法 (PEG) 作为描述形式,并使用 Lua 本身作为解析器描述语言的解析器生成器。它包含一个理解 Lua 5.1 完整语法的解析器。(PEG 似乎是一个早于 LPeg 的努力。)
LuaBalanced 提供了一些函数,这些函数可以在字符串中匹配 Lua 代码的定界片段。它假设 Lua 代码在语法上是正确的(这可以在稍后使用 loadstring
验证),从而避免了对 Lua 语法的严格词法分析和解析。
PenLight? 提供了一个仅限 Lua 词法分析器 [4][5],它在 Lua 中实现。
[Yueliang] 在 Lua 中实现了完整的 Lua 编译器。它是 Lua C 代码到 Lua 的相当直接的移植。
Parrot [6] 包含一个用 Perl5 编写的编译器,它将 Lua 5.1 编译成 Parrot VM 字节码(尽管它还在开发中)。还有一个指向 Subversion 存储库的 Web 界面 [7]。
另请参阅相关工作
那些重新实现 Lua 的人可能对 5.1 的测试套件感兴趣 LuaList:2006-03/msg00716.html 和 5.0 LuaList:2005-12/msg00312.html。
Parse2004 年 8 月,Rici Lake 在 lua 邮件列表中宣布了一个新的 Lua 5.0 解析器,它在 Lua 中实现:[LuaParse]。
[Lua2js] 包含使用 Gentle[8] 编译器构建工具包完成的 Lua 5.0 的完整语法。
lua-xgettext 工具包含一个 Haskell/Parsec 解析器:LuaList:2006-10/msg00609.html
一个几乎完整的 Lua 5.0 C++ 解析器,它使用来自 Boost 的 Spirit:http://article.gmane.org/gmane.comp.parsers.spirit.general/4846
这似乎是一个很好的开始,可以用于在您自己的需要 C++ 中的 Lua 解释器的东西中重复使用。作者已经放弃了这个项目,上面是截至 2004 年 2 月的最新版本。在 2005 年 2 月,我更仔细地查看了这个语法,试图使用它。它有一些问题
最后一个问题对我来说是一个阻碍。因此,我未能让 Spirit 正确解析 Lua。
-- Asger Ottar Alstrup (aalstrup at laerdal.dk)
我为 SZARP SCADA 系统编写了另一个 spirit 解析器。它主要针对简单情况进行测试,在这种情况下,我们可以绕过实际的 lua 并执行语句而无需诉诸虚拟机,但总的来说,它似乎运行良好。它不应受到上述缺陷的影响,并且使用最新的 spirit API 编写。它可能难以立即使用,因为它是一个更大系统的一部分,但它的依赖关系仍然很少。
解析器文件可以在这里找到:http://szarp.git.sourceforge.net/git/gitweb.cgi?p=szarp/szarp;a=tree;f=libSzarp2;hb=master 它被分成四个文件:include/lua_syntax.h 和 szbase/lua_parser.cc、szbase/lua_parser_extra.cc、szbase/lua_parser_extra.h
如有任何问题,请给我发邮件:Darek Marcinkiewicz (reksio at newterm.pl)
一个在 Java 中实现的 Lua 4 不完整解释器:http://www.hetland.org/jlua/ (链接已失效)
[Lua-ml] 是 Lua 2.5 在 OCaml 中的实现。解析器使用一些 OCaml 解析器生成器构建,并封装在一些文学编程系统中。
Lua 5.1 语法在 Lemon 中--RiciLake [在 LJS 中实现]
%fallback OPEN '(' . chunk ::= block . semi ::= ';' . semi ::= . block ::= scope statlist . block ::= scope statlist laststat semi . ublock ::= block 'until' exp . scope ::= . scope ::= scope statlist binding semi. statlist ::= . statlist ::= statlist stat semi . stat ::= 'do' block 'end' . stat ::= 'while' exp 'do' block 'end' . stat ::= repetition 'do' block 'end' . stat ::= 'repeat' ublock . stat ::= 'if' conds 'end' . stat ::= 'function' funcname funcbody . stat ::= setlist '=' explist1 . stat ::= functioncall . repetition ::= 'for' NAME '=' explist23 . repetition ::= 'for' namelist 'in' explist1 . conds ::= condlist . conds ::= condlist 'else' block . condlist ::= cond . condlist ::= condlist 'elseif' cond . cond ::= exp 'then' block . laststat ::= 'break' . laststat ::= 'return' . laststat ::= 'return' explist1 . binding ::= 'local' namelist . binding ::= 'local' namelist '=' explist1 . binding ::= 'local' 'function' NAME funcbody . funcname ::= dottedname . funcname ::= dottedname ':' NAME . dottedname ::= NAME . dottedname ::= dottedname '.' NAME . namelist ::= NAME . namelist ::= namelist ',' NAME . explist1 ::= exp . explist1 ::= explist1 ',' exp . explist23 ::= exp ',' exp . explist23 ::= exp ',' exp ',' exp . %left 'or' . %left 'and' . %left '<' '<=' '>' '>=' '==' '~=' . %right '..' . %left '+' '-' . %left '*' '/' '%' . %right 'not' '#' . %right '^' . exp ::= 'nil'|'true'|'false'|NUMBER|STRING|'...' . exp ::= function . exp ::= prefixexp . exp ::= tableconstructor . exp ::= 'not'|'#'|'-' exp . ['not'] exp ::= exp 'or' exp . exp ::= exp 'and' exp . exp ::= exp '<'|'<='|'>'|'>='|'=='|'~=' exp . exp ::= exp '..' exp . exp ::= exp '+'|'-' exp . exp ::= exp '*'|'/'|'%' exp . exp ::= exp '^' exp . setlist ::= var . setlist ::= setlist ',' var . var ::= NAME . var ::= prefixexp '[' exp ']' . var ::= prefixexp '.' NAME . prefixexp ::= var . prefixexp ::= functioncall . prefixexp ::= OPEN exp ')' . functioncall ::= prefixexp args . functioncall ::= prefixexp ':' NAME args . args ::= '(' ')' . args ::= '(' explist1 ')' . args ::= tableconstructor . args ::= STRING . function ::= 'function' funcbody . funcbody ::= params block 'end' . params ::= '(' parlist ')' . parlist ::= . parlist ::= namelist . parlist ::= '...' . parlist ::= namelist ',' '...' . tableconstructor ::= '{' '}' . tableconstructor ::= '{' fieldlist '}' . tableconstructor ::= '{' fieldlist ','|';' '}' . fieldlist ::= field . fieldlist ::= fieldlist ','|';' field . field ::= exp . field ::= NAME '=' exp . field ::= '[' exp ']' '=' exp .