Permalink
Browse files

Update to LPeg 0.10.2

  • Loading branch information...
1 parent 5019d49 commit 14b436c2d72e633a6c4eef0fe1af099deedc99b8 kapec committed Aug 19, 2011
Showing with 105 additions and 19 deletions.
  1. +2 −0 HISTORY
  2. +1 −1 dist.info
  3. +10 −5 lpeg.c
  4. +7 −6 lpeg.html
  5. +79 −4 re.html
  6. +2 −2 re.lua
  7. +4 −1 test.lua
View
2 HISTORY
@@ -10,6 +10,8 @@ HISTORY for LPeg 0.10
+ works with Lua 5.2
+ consumes less C stack
+ - "and" predicates do not keep captures
+
* Changes from version 0.8 to 0.9
-------------------------------
+ The accumulator capture was replaced by a fold capture;
View
2 dist.info
@@ -1,7 +1,7 @@
--- This file is part of LuaDist project
name = "lpeg"
-version = "0.10"
+version = "0.10.2"
desc = "Parsing Expression Grammars For Lua"
author = "Roberto Ierusalimschy"
View
15 lpeg.c
@@ -1,5 +1,5 @@
/*
-** $Id: lpeg.c,v 1.112 2010/11/03 17:07:50 roberto Exp $
+** $Id: lpeg.c,v 1.114 2011/02/16 15:02:20 roberto Exp $
** LPeg - PEG pattern matching for Lua
** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license)
** written by Roberto Ierusalimschy
@@ -209,6 +209,8 @@ typedef struct Capture {
#define setchar(st,c) ((st)[(c) >> 3] |= (1 << ((c) & 7)))
+static int target (Instruction *p, int i);
+
static int sizei (const Instruction *i) {
switch((Opcode)i->i.code) {
@@ -245,7 +247,7 @@ static int getposition (lua_State *L, int t, int i) {
/*
** {======================================================
-** Printing patterns
+** Printing patterns (for debugging)
** =======================================================
*/
@@ -350,6 +352,7 @@ static void printpatt (Instruction *p) {
}
+#if 0
static void printcap (Capture *cap) {
printcapkind(cap->kind);
printf(" (idx: %d - size: %d) -> %p\n", cap->idx, cap->siz, cap->s);
@@ -359,6 +362,7 @@ static void printcap (Capture *cap) {
static void printcaplist (Capture *cap) {
for (; cap->s; cap++) printcap(cap);
}
+#endif
/* }====================================================== */
@@ -785,7 +789,8 @@ static void checkrule (lua_State *L, Instruction *op, int from, int to,
for (i = from; i < to; i += sizei(op + i)) {
if (op[i].i.code == IPartialCommit && op[i].i.offset < 0) { /* loop? */
int start = dest(op, i);
- assert(op[start - 1].i.code == IChoice && dest(op, start - 1) == i + 1);
+ assert(op[start - 1].i.code == IChoice &&
+ dest(op, start - 1) == target(op, i + 1));
if (start <= lastopen) { /* loop does contain an open call? */
if (!verify(L, op, op + start, op + i, postable, rule)) /* check body */
luaL_error(L, "possible infinite loop in %s", val2str(L, rule));
@@ -2345,7 +2350,7 @@ static int matchl (lua_State *L) {
}
-static struct luaL_reg pattreg[] = {
+static struct luaL_Reg pattreg[] = {
{"match", matchl},
{"print", printpat_l},
{"locale", locale_l},
@@ -2371,7 +2376,7 @@ static struct luaL_reg pattreg[] = {
};
-static struct luaL_reg metapattreg[] = {
+static struct luaL_Reg metapattreg[] = {
{"__add", union_l},
{"__pow", star_l},
{"__sub", diff_l},
View
13 lpeg.html
@@ -10,7 +10,7 @@
</head>
<body>
-<!-- $Id: lpeg.html,v 1.60 2010/11/03 17:42:07 roberto Exp $ -->
+<!-- $Id: lpeg.html,v 1.64 2011/02/16 15:01:58 roberto Exp $ -->
<div id="container">
@@ -705,7 +705,7 @@
</p>
-<h3><a name="cap-cc"></a><code>lpeg.Cc ({value})</code></h3>
+<h3><a name="cap-cc"></a><code>lpeg.Cc ([value, ...])</code></h3>
<p>
Creates a <em>constant capture</em>.
This pattern matches the empty string and
@@ -1243,8 +1243,9 @@
</p>
<pre class="example">
-open = "[" * lpeg.Cg(lpeg.P"="^0, "init") * "[" * lpeg.P"\n"^-1
-close = "]" * lpeg.C(lpeg.P"="^0) * "]"
+equals = lpeg.P"="^0
+open = "[" * lpeg.Cg(equals, "init") * "[" * lpeg.P"\n"^-1
+close = "]" * lpeg.C(equals) * "]"
closeeq = lpeg.Cmt(close * lpeg.Cb("init"), function (s, i, a, b) return a == b end)
string = open * lpeg.C((lpeg.P(1) - closeeq)^0) * close /
function (s, o) return s end
@@ -1368,7 +1369,7 @@
<h2><a name="download"></a>Download</h2>
<p>LPeg
-<a href="http://www.inf.puc-rio.br/~roberto/lpeg/lpeg-0.10.tar.gz">source code</a>.</p>
+<a href="http://www.inf.puc-rio.br/~roberto/lpeg/lpeg-0.10.2.tar.gz">source code</a>.</p>
<h2><a name="license">License</a></h2>
@@ -1412,7 +1413,7 @@
<div id="about">
<p><small>
-$Id: lpeg.html,v 1.60 2010/11/03 17:42:07 roberto Exp $
+$Id: lpeg.html,v 1.64 2011/02/16 15:01:58 roberto Exp $
</small></p>
</div> <!-- id="about" -->
View
83 re.html
@@ -10,7 +10,7 @@
</head>
<body>
-<!-- $Id: re.html,v 1.14 2010/11/03 17:07:19 roberto Exp $ -->
+<!-- $Id: re.html,v 1.17 2011/01/10 15:08:06 roberto Exp $ -->
<div id="container">
@@ -154,6 +154,13 @@
Otherwise, returns nil.
</p>
+<p>
+An optional numeric argument <code>init</code> makes the search
+starts at that position in the subject string.
+As usual in Lua libraries,
+a negative value counts from the end.
+</p>
+
<h3><code>re.match (subject, pattern)</code></h3>
<p>
Matches the given pattern against the given subject.
@@ -225,13 +232,81 @@
</p>
<pre class="example">
c = re.compile([[
- longstring &lt;- ('[' {:eq: '='* :} '[' close) =&gt; void
+ longstring &lt;- ('[' {:eq: '='* :} '[' close) -&gt; void
close &lt;- ']' =eq ']' / . close
-]], {void = function () return true end})
+]], {void = function () end})
print(c:match'[==[]]===]]]]==]===[]') --&gt; 17
</pre>
+<h3>Abstract Syntax Trees</h3>
+<p>
+This example shows a simple way to build an
+abstract syntax tree (AST) for a given grammar.
+To keep our example simple,
+let us consider the following grammar
+for lists of names:
+</p>
+<pre class="example">
+p = re.compile[[
+ listname &lt;- (name s)*
+ name &lt;- [a-z][a-z]*
+ s &lt;- %s*
+]]
+</pre>
+<p>
+Now, we will add captures to build a corresponding AST.
+As a first step, the pattern will build a table to
+represent each non terminal;
+terminals will be represented by their corresponding strings:
+</p>
+<pre class="example">
+c = re.compile[[
+ listname &lt;- (name s)* -&gt; {}
+ name &lt;- {[a-z][a-z]*} -&gt; {}
+ s &lt;- %s*
+]]
+</pre>
+<p>
+Now, a match against <code>"hi hello bye"</code>
+results in the table
+<code>{{"hi"}, {"hello"}, {"bye"}}</code>.
+</p>
+<p>
+For such a simple grammar,
+this AST is more than enough;
+actually, the tables around each single name
+are already overkilling.
+More complex grammars,
+however, may need some more structure.
+Specifically,
+it would be useful if each table had
+a <code>tag</code> field telling what non terminal
+that table represents.
+We can add such a tag using
+<a href="lpeg.html/#cap-g">named group captures</a>:
+</p>
+<pre class="example">
+x = re.compile[[
+ listname <- ({:tag: '' -> 'list':} (name s)*) -> {}
+ name <- ({:tag: '' -> 'id':} {[a-z][a-z]*}) -> {}
+ s <- ' '*
+]]
+</pre>
+<p>
+With these group captures,
+a match against <code>"hi hello bye"</code>
+results in the following table:
+</p>
+<pre class="example">
+{tag="list",
+ {tag="id", "hi"},
+ {tag="id", "hello"},
+ {tag="id", "bye"}
+}
+</pre>
+
+
<h3>Indented blocks</h3>
<p>
This example breaks indented blocks into tables,
@@ -401,7 +476,7 @@
<div id="about">
<p><small>
-$Id: re.html,v 1.14 2010/11/03 17:07:19 roberto Exp $
+$Id: re.html,v 1.17 2011/01/10 15:08:06 roberto Exp $
</small></p>
</div> <!-- id="about" -->
View
4 re.lua
@@ -1,4 +1,4 @@
--- $Id: re.lua,v 1.38 2010/11/03 17:21:07 roberto Exp $
+-- $Id: re.lua,v 1.39 2010/11/04 19:44:18 roberto Exp $
-- imported functions and modules
local tonumber, type, print, error = tonumber, type, print, error
@@ -102,7 +102,7 @@ local function equalcap (s, i, c)
end
-local S = (Predef.space + "--" * (any - Predef.nl)^0)^0
+local S = (m.S(" \f\n\r\t\v") + "--" * (any - Predef.nl)^0)^0
local name = m.R("AZ", "az") * m.R("AZ", "az", "__", "09")^0
View
5 test.lua
@@ -1,6 +1,6 @@
#!/usr/bin/env lua5.1
--- $Id: test.lua,v 1.81 2010/11/03 17:07:50 roberto Exp $
+-- $Id: test.lua,v 1.82 2010/12/03 14:49:54 roberto Exp $
require"strict" -- just to be pedantic
@@ -348,6 +348,9 @@ checkerr("rule <a table> is not defined", m.match, { m.V({}) }, "")
print('+')
+-- bug in 0.10 (rechecking a grammar, after tail-call optimization)
+m.P{ m.P { (m.P(3) + "xuxu")^0 * m.V"xuxu", xuxu = m.P(1) } }
+
local V = m.V
local Space = m.S(" \n\t")^0

0 comments on commit 14b436c

Please sign in to comment.