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