aboutsummaryrefslogtreecommitdiff
path: root/lpeg.html
diff options
context:
space:
mode:
Diffstat (limited to 'lpeg.html')
-rw-r--r--lpeg.html89
1 files changed, 80 insertions, 9 deletions
diff --git a/lpeg.html b/lpeg.html
index f50d327..9faa1c7 100644
--- a/lpeg.html
+++ b/lpeg.html
@@ -638,6 +638,10 @@ or no value when <code>number</code> is zero.</td></tr>
638<tr><td><a href="#cap-func"><code>patt / function</code></a></td> 638<tr><td><a href="#cap-func"><code>patt / function</code></a></td>
639 <td>the returns of <code>function</code> applied to the captures 639 <td>the returns of <code>function</code> applied to the captures
640 of <code>patt</code></td></tr> 640 of <code>patt</code></td></tr>
641<tr><td><a href="#cap-rep"><code>patt % function</code></a></td>
642 <td>the return of <code>function</code> applied to the previous
643 capture plus the captures of <code>patt</code></td></tr>;
644 the returned value becomes the value of the previous capture
641<tr><td><a href="#matchtime"><code>lpeg.Cmt(patt, function)</code></a></td> 645<tr><td><a href="#matchtime"><code>lpeg.Cmt(patt, function)</code></a></td>
642 <td>the returns of <code>function</code> applied to the captures 646 <td>the returns of <code>function</code> applied to the captures
643 of <code>patt</code>; the application is done at match time</td></tr> 647 of <code>patt</code>; the application is done at match time</td></tr>
@@ -889,6 +893,75 @@ there is no captured value.
889</p> 893</p>
890 894
891 895
896<h3><a name="cap-rep"></a><code>patt % function</code></h3>
897<p>
898Creates an <em>accumulator capture</em>.
899This pattern behaves similarly to a
900<a href="cap-func">function capture</a>,
901with the following differences:
902The last captured value is added as a first argument to
903the call;
904the return of the function is adjusted to one single value;
905that value becomes the last captured value.
906</p>
907
908<p>
909As an example,
910consider the following code fragment:
911</p>
912<pre class="example">
913local name = lpeg.C(lpeg.R("az")^1)
914local p = name * (lpeg.P("^") % string.upper)^-1
915print(p:match("count")) --&gt; count
916print(p:match("count^")) --&gt; COUNT
917</pre>
918<p>
919In the first match,
920the accumulator capture does not match,
921and so the match results in its first capture, a name.
922In the second match,
923the accumulator capture matches,
924so the function <code>string.upper</code>
925is called with the previous capture (created by <code>name</code>)
926plus the string <code>"^"</code>;
927the function ignores its second argument and returns the first argument
928changed to upper case;
929that value then becomes the first and only
930capture value created by the match.
931</p>
932-- matches a numeral and captures its numerical value
933number = lpeg.R"09"^1 / tonumber
934
935-- auxiliary function to add two numbers
936function add (acc, newvalue) return acc + newvalue end
937
938-- matches a list of numbers, adding their values
939sum = number * ("," * number % add)^0
940
941-- example of use
942print(sum:match("10,30,43")) --&gt; 83
943</pre>
944<p>
945First, the initial <code>number</code> captures a number;
946that first capture will play the role of an accumulator.
947Then, each time <code>number</code> matches inside the loop
948there is a accumulator capture:
949It calls <code>add</code> with the current value of the accumulator
950and the value of the new number,
951and their sum replaces the value of the accumulator.
952At the end of the match,
953the accumulator with all sums is the final value.
954</p>
955
956<p>
957Due to the nature of this capture,
958you should avoid using it in places where it is not clear
959what is its "previous" capture.
960Due to implementation details,
961you should not use this capture inside a substitution capture.
962</p>
963
964
892<h3><a name="matchtime"></a><code>lpeg.Cmt(patt, function)</code></h3> 965<h3><a name="matchtime"></a><code>lpeg.Cmt(patt, function)</code></h3>
893<p> 966<p>
894Creates a <em>match-time capture</em>. 967Creates a <em>match-time capture</em>.
@@ -968,19 +1041,17 @@ lpeg.locale(lpeg) -- adds locale entries into 'lpeg' table
968local space = lpeg.space^0 1041local space = lpeg.space^0
969local name = lpeg.C(lpeg.alpha^1) * space 1042local name = lpeg.C(lpeg.alpha^1) * space
970local sep = lpeg.S(",;") * space 1043local sep = lpeg.S(",;") * space
971local pair = lpeg.Cg(name * "=" * space * name) * sep^-1 1044local pair = name * "=" * space * name * sep^-1
972local list = lpeg.Cf(lpeg.Ct("") * pair^0, rawset) 1045local list = lpeg.Ct("") * (pair % rawset)^0
973t = list:match("a=b, c = hi; next = pi") --> { a = "b", c = "hi", next = "pi" } 1046t = list:match("a=b, c = hi; next = pi") --> { a = "b", c = "hi", next = "pi" }
974</pre> 1047</pre>
975<p> 1048<p>
976Each pair has the format <code>name = name</code> followed by 1049Each pair has the format <code>name = name</code> followed by
977an optional separator (a comma or a semicolon). 1050an optional separator (a comma or a semicolon).
978The <code>pair</code> pattern encloses the pair in a group pattern, 1051The <code>list</code> pattern then <em>folds</em> these captures.
979so that the names become the values of a single capture.
980The <code>list</code> pattern then folds these captures.
981It starts with an empty table, 1052It starts with an empty table,
982created by a table capture matching an empty string; 1053created by a table capture matching an empty string;
983then for each capture (a pair of names) it applies <code>rawset</code> 1054then for each a pair of names it applies <code>rawset</code>
984over the accumulator (the table) and the capture values (the pair of names). 1055over the accumulator (the table) and the capture values (the pair of names).
985<code>rawset</code> returns the table itself, 1056<code>rawset</code> returns the table itself,
986so the accumulator is always the table. 1057so the accumulator is always the table.
@@ -1295,8 +1366,8 @@ end
1295-- Grammar 1366-- Grammar
1296local V = lpeg.V 1367local V = lpeg.V
1297G = lpeg.P{ "Exp", 1368G = lpeg.P{ "Exp",
1298 Exp = lpeg.Cf(V"Term" * lpeg.Cg(TermOp * V"Term")^0, eval); 1369 Exp = V"Term" * (TermOp * V"Term" % eval)^0;
1299 Term = lpeg.Cf(V"Factor" * lpeg.Cg(FactorOp * V"Factor")^0, eval); 1370 Term = V"Factor" * (FactorOp * V"Factor" % eval)^0;
1300 Factor = Number / tonumber + Open * V"Exp" * Close; 1371 Factor = Number / tonumber + Open * V"Exp" * Close;
1301} 1372}
1302 1373
@@ -1304,7 +1375,7 @@ G = lpeg.P{ "Exp",
1304print(lpeg.match(G, "3 + 5*9 / (1+1) - 12")) --> 13.5 1375print(lpeg.match(G, "3 + 5*9 / (1+1) - 12")) --> 13.5
1305</pre> 1376</pre>
1306<p> 1377<p>
1307Note the use of the fold (accumulator) capture. 1378Note the use of the accumulator capture.
1308To compute the value of an expression, 1379To compute the value of an expression,
1309the accumulator starts with the value of the first term, 1380the accumulator starts with the value of the first term,
1310and then applies <code>eval</code> over 1381and then applies <code>eval</code> over