`
mryufeng
  • 浏览: 985589 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

LPeg Parsing Expression Grammars For Lua, version

    博客分类:
  • Lua
阅读更多
Introduction

LPeg is a new pattern-matching library for Lua, based on Parsing Expression Grammars (PEGs). In this text, I assume you are familiar with PEGs. If you are not, you can get a quick start reading the Wikipedia Entry for PEGs or Section 2 of Parsing Expression Grammars: A Recognition-Based Syntactic Foundation (the section has only one page). The nice thing about PEGs is that it has a formal basis (instead of being an ad-hoc set of features), allows an efficient and simple implementation, and does most things we expect from a pattern-matching library (and more, as we can define entire grammars).

作者是Lua语言的Robert, 2100行ANSI c代码, 和boost:spirit差不多强大。我等有福气了,做个小型的文法分析器轻轻松松.  作者200行用lpeg实现了一个regex模块. 一起来吧, lua也有了yacc & lex.



  • lpeg-tug.rar (107.4 KB)
  • 描述: lpeg-tug pdf
  • 下载次数: 19
分享到:
评论
1 楼 mryufeng 2008-07-14  
mysql-proxy的作者jan用lpeg写了个mysql 的select语法, The whole thing was about 6 hours of work without knowing LPEG before, the final indenter is only a few lines of LUA。 开发效率够高!!!

local l = require("lpeg")

module("sql")

---
-- turn a string into a case-insensitive lpeg-pattern
--
function lpeg_ci_str(s)
local p

for i = 1, #s do
local c = s:sub(i, i)

local lp = l.S(c:upper() .. c:lower() )

if p then
p = p * lp
else
p = lp
end
end

return p
end

slash_comment  = l.P("/*") * ( 1 - l.P("*/") )^0 * l.P("*/")
-- FIXME: we need support for -- comments too
comment = slash_comment

WS       = l.S(" \t\n") + comment
SELECT   = lpeg_ci_str("SELECT") * WS^1
STAR     = l.P("*") * WS^0
FROM     = lpeg_ci_str("FROM") * WS^1
alpha    = l.R("az", "AZ") -- [a-zA-Z]
digit    = l.R("09")       -- [0-9]
number   = (l.P("-") + "") * digit^1         -- [0-9]+
literal_char = alpha + l.S("_") -- /[_a-z]/i
literal_unquoted  = literal_char * ( literal_char + digit )^0  -- /[_a-z][_a-z0-9]*/i
literal_quoted  = l.P("`") * ( 1 - l.P("`") )^0 * l.P("`") -- /`.*`/
string_quoted  = l.P("\"") * ( 1 - l.P("\"") )^0 * l.P("\"") -- /".*"/
literal  = literal_unquoted + literal_quoted

fieldname  = literal * ( WS^0 * l.P(".") * WS^0 * literal ) ^0

---
-- expressions
--

funcname   = literal_unquoted
user_var   = "@" * literal_unquoted * WS^0
NULL       = lpeg_ci_str("NULL")
LogicalOp  = (lpeg_ci_str("OR") + lpeg_ci_str("AND")) * WS^1
AssignOp   = l.P(":=") * WS^0
FactorOp   = l.S("*/") * WS^0
TermOp     = l.S("+-") * WS^0
CompOp     = (
l.P("=") +
l.P("!=") +
l.P("<>") +
l.P("<=") +
l.P(">=") +
l.P("<") +
l.P(">") +
lpeg_ci_str("IS") * WS^1 * lpeg_ci_str("NOT") +
lpeg_ci_str("IS") * WS) * WS^0
ParanOpen = l.P("(") * WS^0
ParanClose = l.P(")") * WS^0
Comma = l.P(",") * WS^0

Assign  = l.V("Assign") * WS^0
Exp     = l.V("Exp") * WS^0
Logical = l.V("Logical") * WS^0
Comp    = l.V("Comp") * WS^0
Factor  = l.V("Factor") * WS^0
Term    = l.V("Term") * WS^0

expr       = l.P({
Assign,
Assign   = (( user_var * AssignOp ) + "") * Exp,
Exp      = Logical * ( LogicalOp * Logical)^0,
Logical  = Comp * ( CompOp * Comp)^0,
Comp     = Factor * ( FactorOp * Factor)^0,
Factor   = Term * ( TermOp * Term )^0,
Term     =
lpeg_ci_str("CAST") * ParanOpen * Assign * lpeg_ci_str("AS") * WS^1 * literal_unquoted * ParanClose +
funcname * ParanOpen * (( Assign * ( Comma * Assign )^0) + "") * ParanClose +
ParanOpen * Assign * ParanClose +
number +
string_quoted +
user_var +
fieldname +
NULL
})

alias = lpeg_ci_str("AS") * WS^1 * literal * WS^0
opt_alias = ((alias) + "")
alias_expr = expr * opt_alias

select_opt = (l.P("SQL_CALC_FOUND_ROWS") + l.P("SQL_NO_CACHE")) * WS^1

table = literal * WS^0
alias_table = table * opt_alias
WHERE = lpeg_ci_str("WHERE") * WS^0
USING = lpeg_ci_str("USING") * WS^0
LEFT = lpeg_ci_str("LEFT") * WS^0
RIGHT = lpeg_ci_str("RIGHT") * WS^0
INNER = lpeg_ci_str("INNER") * WS^0
OUTER = lpeg_ci_str("OUTER") * WS^0
JOIN = lpeg_ci_str("JOIN") * WS^0
join_type =
  ((INNER + "") * JOIN) +
  (LEFT * (OUTER + "") * JOIN) +
  (RIGHT * (OUTER + "") * JOIN)

ON           = lpeg_ci_str("ON") * WS^0
DESC         = lpeg_ci_str("DESC") * WS^0
ASC          = lpeg_ci_str("ASC") * WS^0
ORDERBY      = lpeg_ci_str("ORDER") * WS^1 * lpeg_ci_str("BY") * WS^0
orderby_expr = expr * (ASC + DESC + "")
GROUPBY      = lpeg_ci_str("GROUP") * WS^1 * lpeg_ci_str("BY") * WS^0
HAVING       = lpeg_ci_str("HAVING") * WS^0

select_pat = l.P({
"simple_select",

simple_select = l.C(SELECT) *
l.Ct((l.C(select_opt))^0) *
l.Ct(l.C(alias_expr) * (l.C(Comma * alias_expr))^0) *
(-1 +
(l.C(FROM) *  -- FROM tbl [AS alias] [, tbl [AS alias]]
   l.Ct(l.V("subq_table") *
    (((l.C(Comma) * l.V("subq_table")) +
              l.C((join_type)) * l.Ct(l.V("subq_table")) *
                        ((l.C(USING) * l.Ct(l.C(ParanOpen * fieldname * ParanClose))) +
                         (l.C(ON) * l.Ct(l.C(expr))) + "")))^0)) *
   (-1 + -- [WHERE ...]
    ((l.C(WHERE) * l.Ct(l.C(expr))) + "") *
            ((l.C(ORDERBY) * l.Ct(l.C(orderby_expr) * ( l.C(Comma * orderby_expr))^0)) + "") *
            ((l.C(GROUPBY) * l.Ct(l.C(expr) * ( l.C(Comma * expr))^0) * ( l.C(HAVING) * l.Ct(l.C(expr)) + "")) + "")
           ) + "") +
"",

subq_table = l.C(alias_table) +
l.C(ParanOpen) * l.Ct(l.V("simple_select")) * l.C(ParanClose * alias )
})

相关推荐

    Lpeg文档翻译

    lpeg的文档翻译 http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html LPeg Parsing Expression Grammars For Lua, version 0.12

    DSL:Lua 的领域特定语言生成器

    DSL 基于 LPEG(Lua Parsing Expression Grammars),因此标记和规则以 LPEG 语法进行描述。 DSL 通过添加对编写自定义语言有用的功能来扩展 LPEG,例如诊断工具、错误处理和一些可用于编写模式的新原语。DSL特性...

    lpeg-grammars:LPEG 词法分析器的一组语法

    Lua 5.1.x 或 LuaJIT 2.0.x+ LPEG 库 用法 解析 HTML 文档 local htmlParser = require ' lexers/html ' local content = htmlParser. parse ( [[ &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;...

    tableshape:在React.PropTypes和LPeg的启发下测试Lua表的形状或结构

    桌子形状 Lua库,用于验证表的形状(架构,结构等),并在必要时进行转换。 类型检查语法的灵感来自的。 可以使用类似于的运算符重载语法来表示复杂的类型和值转换。安装$ luarocks install tableshape快速使用local...

    lua-luaepnf:扩展PEG注释格式(LPeg的简单语法)

    LPeg(Parsing Expression Grammar)是Lua中的一种强大的解析工具,它基于派生自Packrat解析的原理,允许程序员用一种直观的模式匹配方式定义语法规则。LPeg的优势在于其高效和灵活性,但默认的语法对于处理注释和...

    lua-parser:用LPegLabel编写的Lua 5.3解析器

    lua-parser 这是一个Lua 5.3解析器书面 ,在一种格式类似于由所指定的一个生成AST 。 解析器使用LPegLabel提供更具体的错误消息。要求 lua &gt;= 5.1 lpeglabel &gt;= 1.6.0原料药包lua-parser有两个模块: lua-parser....

    lpeg-0.12.2-struct-0.2

    LPEG(Lua Pattern Grammar)和Struct就是这样的两个工具,它们在文本解析和模式匹配方面具有强大的功能。lpeg-0.12.2-struct-0.2组合包将这两个强大的库结合在一起,为开发者提供了更强大的文本处理解决方案。 ...

    lua-lpeg-1.0.1-6.el8.x86_64.rpm

    官方离线安装包,测试可用。请使用rpm -ivh [rpm完整包名] 进行安装

    lua-lpeg-1.0.1-6.el8.aarch64.rpm

    官方离线安装包,亲测可用

    lpeg-0.12.2.tar.gz

    LPEG(Lua Pattern Grammar)是一个强大的解析表达式库,由巴西圣保罗大学的Cesar Hidalgo和Koichi Sasada开发,是Lua编程语言的一个扩展。LPEG提供了一种基于语法规则的模式匹配机制,允许开发者编写复杂的文本解析...

    windows环境安装lua

    6. **扩展库与模块**:Lua标准库虽然简洁,但可以通过C语言编写的扩展库增加功能,例如LuaSocket用于网络通信,Lpeg提供强大的正则表达式功能等。这些库通常以动态链接库(.dll)形式存在,需要将其放在与lua.exe...

    LuaForWindows_v5.1.5-52编译器

    在编程实践中,你可以利用LuaForWindows提供的各种库,如socket库进行网络通信,luarocks进行包管理,或者lpeg进行正则表达式处理。对于游戏开发,Lua常被用来编写游戏逻辑和脚本,因为它与C++等系统级语言的接口...

    lua-language-server:Lua编码的Lua语言服务器

    lua-language-server利用LPEG(Lua Patterns for Grammar)库来解析和理解Lua语法。LPEG是一种强大的模式匹配库,可以用来定义复杂的语法规则,对于构建语言服务器这种需要深入理解语言结构的项目非常有用。 ### 4....

    Lua中文参考----学习Lua的好资料

    10. **社区和扩展**:Lua拥有活跃的社区,提供了众多第三方库和扩展,增强了Lua的功能,例如LPEG(Lua的正则表达式库)和Corona SDK(用于移动应用开发)。 通过阅读这份"Lua中文参考",你可以系统地学习Lua的所有...

    lua5.3+luarocks-3.7.0-windows-64.zip

    例如,如果你想安装一个名为 "lpeg" 的库,只需在命令行输入 `luarocks install lpeg`。这将自动下载、编译(如果需要)并安装库,使其对你的 Lua 环境可用。 Lua 的广泛应用包括游戏开发、网络编程、嵌入式系统、...

    lpeg_patterns:LPEG模式的集合

    LPEG是基于PEG(Parsing Expression Grammar)理论的,它允许开发者创建更复杂的解析器,而不仅仅是简单的模式匹配。本文将围绕“lpeg_patterns”这个项目,深入探讨LPEG模式集合的使用与实现。 “lpeg_patterns”...

    lpeg-0.9.tar.gz_SPRINT

    《深入理解LPEG:Lua实现的Sprint解析库》 在编程世界中,解析库扮演着至关重要的角色,它们能够帮助我们处理各种复杂的文本输入,转换数据格式,以及执行高级的文本分析。当我们谈论“lpeg-0.9.tar.gz_SPRINT”时...

Global site tag (gtag.js) - Google Analytics