immunio 0.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +234 -0
  3. data/README.md +147 -0
  4. data/bin/immunio +5 -0
  5. data/lib/immunio.rb +29 -0
  6. data/lib/immunio/agent.rb +260 -0
  7. data/lib/immunio/authentication.rb +96 -0
  8. data/lib/immunio/blocked_app.rb +38 -0
  9. data/lib/immunio/channel.rb +432 -0
  10. data/lib/immunio/cli.rb +39 -0
  11. data/lib/immunio/context.rb +114 -0
  12. data/lib/immunio/errors.rb +43 -0
  13. data/lib/immunio/immunio_ca.crt +45 -0
  14. data/lib/immunio/logger.rb +87 -0
  15. data/lib/immunio/plugins/action_dispatch.rb +45 -0
  16. data/lib/immunio/plugins/action_view.rb +431 -0
  17. data/lib/immunio/plugins/active_record.rb +707 -0
  18. data/lib/immunio/plugins/active_record_relation.rb +370 -0
  19. data/lib/immunio/plugins/authlogic.rb +80 -0
  20. data/lib/immunio/plugins/csrf.rb +24 -0
  21. data/lib/immunio/plugins/devise.rb +40 -0
  22. data/lib/immunio/plugins/environment_reporter.rb +69 -0
  23. data/lib/immunio/plugins/eval.rb +51 -0
  24. data/lib/immunio/plugins/exception_handler.rb +55 -0
  25. data/lib/immunio/plugins/gems_tracker.rb +5 -0
  26. data/lib/immunio/plugins/haml.rb +36 -0
  27. data/lib/immunio/plugins/http_finisher.rb +50 -0
  28. data/lib/immunio/plugins/http_tracker.rb +203 -0
  29. data/lib/immunio/plugins/io.rb +96 -0
  30. data/lib/immunio/plugins/redirect.rb +42 -0
  31. data/lib/immunio/plugins/warden.rb +66 -0
  32. data/lib/immunio/processor.rb +234 -0
  33. data/lib/immunio/rails.rb +26 -0
  34. data/lib/immunio/request.rb +139 -0
  35. data/lib/immunio/rufus_lua_ext/ref.rb +27 -0
  36. data/lib/immunio/rufus_lua_ext/state.rb +157 -0
  37. data/lib/immunio/rufus_lua_ext/table.rb +137 -0
  38. data/lib/immunio/rufus_lua_ext/utils.rb +13 -0
  39. data/lib/immunio/version.rb +5 -0
  40. data/lib/immunio/vm.rb +291 -0
  41. data/lua-hooks/ext/all.c +78 -0
  42. data/lua-hooks/ext/bitop/README +22 -0
  43. data/lua-hooks/ext/bitop/bit.c +189 -0
  44. data/lua-hooks/ext/extconf.rb +38 -0
  45. data/lua-hooks/ext/libinjection/COPYING +37 -0
  46. data/lua-hooks/ext/libinjection/libinjection.h +65 -0
  47. data/lua-hooks/ext/libinjection/libinjection_html5.c +847 -0
  48. data/lua-hooks/ext/libinjection/libinjection_html5.h +54 -0
  49. data/lua-hooks/ext/libinjection/libinjection_sqli.c +2301 -0
  50. data/lua-hooks/ext/libinjection/libinjection_sqli.h +295 -0
  51. data/lua-hooks/ext/libinjection/libinjection_sqli_data.h +9349 -0
  52. data/lua-hooks/ext/libinjection/libinjection_xss.c +531 -0
  53. data/lua-hooks/ext/libinjection/libinjection_xss.h +21 -0
  54. data/lua-hooks/ext/libinjection/lualib.c +109 -0
  55. data/lua-hooks/ext/lpeg/HISTORY +90 -0
  56. data/lua-hooks/ext/lpeg/lpcap.c +537 -0
  57. data/lua-hooks/ext/lpeg/lpcap.h +43 -0
  58. data/lua-hooks/ext/lpeg/lpcode.c +986 -0
  59. data/lua-hooks/ext/lpeg/lpcode.h +34 -0
  60. data/lua-hooks/ext/lpeg/lpeg-128.gif +0 -0
  61. data/lua-hooks/ext/lpeg/lpeg.html +1429 -0
  62. data/lua-hooks/ext/lpeg/lpprint.c +244 -0
  63. data/lua-hooks/ext/lpeg/lpprint.h +35 -0
  64. data/lua-hooks/ext/lpeg/lptree.c +1238 -0
  65. data/lua-hooks/ext/lpeg/lptree.h +77 -0
  66. data/lua-hooks/ext/lpeg/lptypes.h +149 -0
  67. data/lua-hooks/ext/lpeg/lpvm.c +355 -0
  68. data/lua-hooks/ext/lpeg/lpvm.h +58 -0
  69. data/lua-hooks/ext/lpeg/makefile +55 -0
  70. data/lua-hooks/ext/lpeg/re.html +498 -0
  71. data/lua-hooks/ext/lpeg/test.lua +1409 -0
  72. data/lua-hooks/ext/lua-cmsgpack/CMakeLists.txt +45 -0
  73. data/lua-hooks/ext/lua-cmsgpack/README.md +115 -0
  74. data/lua-hooks/ext/lua-cmsgpack/lua_cmsgpack.c +957 -0
  75. data/lua-hooks/ext/lua-cmsgpack/test.lua +570 -0
  76. data/lua-hooks/ext/lua-snapshot/LICENSE +7 -0
  77. data/lua-hooks/ext/lua-snapshot/Makefile +12 -0
  78. data/lua-hooks/ext/lua-snapshot/README.md +18 -0
  79. data/lua-hooks/ext/lua-snapshot/dump.lua +15 -0
  80. data/lua-hooks/ext/lua-snapshot/snapshot.c +455 -0
  81. data/lua-hooks/ext/lua/COPYRIGHT +34 -0
  82. data/lua-hooks/ext/lua/lapi.c +1087 -0
  83. data/lua-hooks/ext/lua/lapi.h +16 -0
  84. data/lua-hooks/ext/lua/lauxlib.c +652 -0
  85. data/lua-hooks/ext/lua/lauxlib.h +174 -0
  86. data/lua-hooks/ext/lua/lbaselib.c +659 -0
  87. data/lua-hooks/ext/lua/lcode.c +831 -0
  88. data/lua-hooks/ext/lua/lcode.h +76 -0
  89. data/lua-hooks/ext/lua/ldblib.c +398 -0
  90. data/lua-hooks/ext/lua/ldebug.c +638 -0
  91. data/lua-hooks/ext/lua/ldebug.h +33 -0
  92. data/lua-hooks/ext/lua/ldo.c +519 -0
  93. data/lua-hooks/ext/lua/ldo.h +57 -0
  94. data/lua-hooks/ext/lua/ldump.c +164 -0
  95. data/lua-hooks/ext/lua/lfunc.c +174 -0
  96. data/lua-hooks/ext/lua/lfunc.h +34 -0
  97. data/lua-hooks/ext/lua/lgc.c +710 -0
  98. data/lua-hooks/ext/lua/lgc.h +110 -0
  99. data/lua-hooks/ext/lua/linit.c +38 -0
  100. data/lua-hooks/ext/lua/liolib.c +556 -0
  101. data/lua-hooks/ext/lua/llex.c +463 -0
  102. data/lua-hooks/ext/lua/llex.h +81 -0
  103. data/lua-hooks/ext/lua/llimits.h +128 -0
  104. data/lua-hooks/ext/lua/lmathlib.c +263 -0
  105. data/lua-hooks/ext/lua/lmem.c +86 -0
  106. data/lua-hooks/ext/lua/lmem.h +49 -0
  107. data/lua-hooks/ext/lua/loadlib.c +705 -0
  108. data/lua-hooks/ext/lua/loadlib_rel.c +760 -0
  109. data/lua-hooks/ext/lua/lobject.c +214 -0
  110. data/lua-hooks/ext/lua/lobject.h +381 -0
  111. data/lua-hooks/ext/lua/lopcodes.c +102 -0
  112. data/lua-hooks/ext/lua/lopcodes.h +268 -0
  113. data/lua-hooks/ext/lua/loslib.c +243 -0
  114. data/lua-hooks/ext/lua/lparser.c +1339 -0
  115. data/lua-hooks/ext/lua/lparser.h +82 -0
  116. data/lua-hooks/ext/lua/lstate.c +214 -0
  117. data/lua-hooks/ext/lua/lstate.h +169 -0
  118. data/lua-hooks/ext/lua/lstring.c +111 -0
  119. data/lua-hooks/ext/lua/lstring.h +31 -0
  120. data/lua-hooks/ext/lua/lstrlib.c +871 -0
  121. data/lua-hooks/ext/lua/ltable.c +588 -0
  122. data/lua-hooks/ext/lua/ltable.h +40 -0
  123. data/lua-hooks/ext/lua/ltablib.c +287 -0
  124. data/lua-hooks/ext/lua/ltm.c +75 -0
  125. data/lua-hooks/ext/lua/ltm.h +54 -0
  126. data/lua-hooks/ext/lua/lua.c +392 -0
  127. data/lua-hooks/ext/lua/lua.def +131 -0
  128. data/lua-hooks/ext/lua/lua.h +388 -0
  129. data/lua-hooks/ext/lua/lua.rc +28 -0
  130. data/lua-hooks/ext/lua/lua_dll.rc +26 -0
  131. data/lua-hooks/ext/lua/luac.c +200 -0
  132. data/lua-hooks/ext/lua/luac.rc +1 -0
  133. data/lua-hooks/ext/lua/luaconf.h +763 -0
  134. data/lua-hooks/ext/lua/luaconf.h.in +724 -0
  135. data/lua-hooks/ext/lua/luaconf.h.orig +763 -0
  136. data/lua-hooks/ext/lua/lualib.h +53 -0
  137. data/lua-hooks/ext/lua/lundump.c +227 -0
  138. data/lua-hooks/ext/lua/lundump.h +36 -0
  139. data/lua-hooks/ext/lua/lvm.c +767 -0
  140. data/lua-hooks/ext/lua/lvm.h +36 -0
  141. data/lua-hooks/ext/lua/lzio.c +82 -0
  142. data/lua-hooks/ext/lua/lzio.h +67 -0
  143. data/lua-hooks/ext/lua/print.c +227 -0
  144. data/lua-hooks/ext/luautf8/README.md +152 -0
  145. data/lua-hooks/ext/luautf8/lutf8lib.c +1274 -0
  146. data/lua-hooks/ext/luautf8/unidata.h +3064 -0
  147. data/lua-hooks/lib/boot.lua +254 -0
  148. data/lua-hooks/lib/encode.lua +4 -0
  149. data/lua-hooks/lib/lexers/LICENSE +21 -0
  150. data/lua-hooks/lib/lexers/bash.lua +134 -0
  151. data/lua-hooks/lib/lexers/bash_dqstr.lua +62 -0
  152. data/lua-hooks/lib/lexers/css.lua +216 -0
  153. data/lua-hooks/lib/lexers/html.lua +106 -0
  154. data/lua-hooks/lib/lexers/javascript.lua +68 -0
  155. data/lua-hooks/lib/lexers/lexer.lua +1575 -0
  156. data/lua-hooks/lib/lexers/markers.lua +33 -0
  157. metadata +308 -0
@@ -0,0 +1,58 @@
1
+ /*
2
+ ** $Id: lpvm.h,v 1.3 2014/02/21 13:06:41 roberto Exp $
3
+ */
4
+
5
+ #if !defined(lpvm_h)
6
+ #define lpvm_h
7
+
8
+ #include "lpcap.h"
9
+
10
+
11
+ /* Virtual Machine's LpegInstructions */
12
+ typedef enum Opcode {
13
+ IAny, /* if no char, fail */
14
+ IChar, /* if char != aux, fail */
15
+ ISet, /* if char not in buff, fail */
16
+ ITestAny, /* in no char, jump to 'offset' */
17
+ ITestChar, /* if char != aux, jump to 'offset' */
18
+ ITestSet, /* if char not in buff, jump to 'offset' */
19
+ ISpan, /* read a span of chars in buff */
20
+ IBehind, /* walk back 'aux' characters (fail if not possible) */
21
+ IRet, /* return from a rule */
22
+ IEnd, /* end of pattern */
23
+ IChoice, /* stack a choice; next fail will jump to 'offset' */
24
+ IJmp, /* jump to 'offset' */
25
+ ICall, /* call rule at 'offset' */
26
+ IOpenCall, /* call rule number 'key' (must be closed to a ICall) */
27
+ ICommit, /* pop choice and jump to 'offset' */
28
+ IPartialCommit, /* update top choice to current position and jump */
29
+ IBackCommit, /* "fails" but jump to its own 'offset' */
30
+ IFailTwice, /* pop one choice and then fail */
31
+ IFail, /* go back to saved state on choice and jump to saved offset */
32
+ IGiveup, /* internal use */
33
+ IFullCapture, /* complete capture of last 'off' chars */
34
+ IOpenCapture, /* start a capture */
35
+ ICloseCapture,
36
+ ICloseRunTime
37
+ } Opcode;
38
+
39
+
40
+
41
+ typedef union LpegInstruction {
42
+ struct Inst {
43
+ byte code;
44
+ byte aux;
45
+ short key;
46
+ } i;
47
+ int offset;
48
+ byte buff[1];
49
+ } LpegInstruction;
50
+
51
+
52
+ void printpatt (LpegInstruction *p, int n);
53
+ const char *lpeg_match (lua_State *L, const char *o, const char *s, const char *e,
54
+ LpegInstruction *op, Capture *capture, int ptop);
55
+
56
+
57
+ #endif
58
+
@@ -0,0 +1,55 @@
1
+ LIBNAME = lpeg
2
+ LUADIR = ../lua/
3
+
4
+ COPT = -O2
5
+ # COPT = -DLPEG_DEBUG -g
6
+
7
+ CWARNS = -Wall -Wextra -pedantic \
8
+ -Waggregate-return \
9
+ -Wcast-align \
10
+ -Wcast-qual \
11
+ -Wdisabled-optimization \
12
+ -Wpointer-arith \
13
+ -Wshadow \
14
+ -Wsign-compare \
15
+ -Wundef \
16
+ -Wwrite-strings \
17
+ -Wbad-function-cast \
18
+ -Wdeclaration-after-statement \
19
+ -Wmissing-prototypes \
20
+ -Wnested-externs \
21
+ -Wstrict-prototypes \
22
+ # -Wunreachable-code \
23
+
24
+
25
+ CFLAGS = $(CWARNS) $(COPT) -std=c99 -I$(LUADIR) -fPIC
26
+ CC = gcc
27
+
28
+ FILES = lpvm.o lpcap.o lptree.o lpcode.o lpprint.o
29
+
30
+ # For Linux
31
+ linux:
32
+ make lpeg.so "DLLFLAGS = -shared -fPIC"
33
+
34
+ # For Mac OS
35
+ macosx:
36
+ make lpeg.so "DLLFLAGS = -bundle -undefined dynamic_lookup"
37
+
38
+ lpeg.so: $(FILES)
39
+ env $(CC) $(DLLFLAGS) $(FILES) -o lpeg.so
40
+
41
+ $(FILES): makefile
42
+
43
+ test: test.lua re.lua lpeg.so
44
+ ./test.lua
45
+
46
+ clean:
47
+ rm -f $(FILES) lpeg.so
48
+
49
+
50
+ lpcap.o: lpcap.c lpcap.h lptypes.h
51
+ lpcode.o: lpcode.c lptypes.h lpcode.h lptree.h lpvm.h lpcap.h
52
+ lpprint.o: lpprint.c lptypes.h lpprint.h lptree.h lpvm.h lpcap.h
53
+ lptree.o: lptree.c lptypes.h lpcap.h lpcode.h lptree.h lpvm.h lpprint.h
54
+ lpvm.o: lpvm.c lpcap.h lptypes.h lpvm.h lpprint.h lptree.h
55
+
@@ -0,0 +1,498 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html>
4
+ <head>
5
+ <title>LPeg.re - Regex syntax for LPEG</title>
6
+ <link rel="stylesheet"
7
+ href="http://www.inf.puc-rio.br/~roberto/lpeg/doc.css"
8
+ type="text/css"/>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
10
+ </head>
11
+ <body>
12
+
13
+ <!-- $Id: re.html,v 1.21 2013/03/28 20:43:30 roberto Exp $ -->
14
+
15
+ <div id="container">
16
+
17
+ <div id="product">
18
+ <div id="product_logo">
19
+ <a href="http://www.inf.puc-rio.br/~roberto/lpeg/">
20
+ <img alt="LPeg logo" src="lpeg-128.gif"/>
21
+ </a>
22
+ </div>
23
+ <div id="product_name"><big><strong>LPeg.re</strong></big></div>
24
+ <div id="product_description">
25
+ Regex syntax for LPEG
26
+ </div>
27
+ </div> <!-- id="product" -->
28
+
29
+ <div id="main">
30
+
31
+ <div id="navigation">
32
+ <h1>re</h1>
33
+
34
+ <ul>
35
+ <li><a href="#basic">Basic Constructions</a></li>
36
+ <li><a href="#func">Functions</a></li>
37
+ <li><a href="#ex">Some Examples</a></li>
38
+ <li><a href="#license">License</a></li>
39
+ </ul>
40
+ </li>
41
+ </ul>
42
+ </div> <!-- id="navigation" -->
43
+
44
+ <div id="content">
45
+
46
+ <h2><a name="basic"></a>The <code>re</code> Module</h2>
47
+
48
+ <p>
49
+ The <code>re</code> module
50
+ (provided by file <code>re.lua</code> in the distribution)
51
+ supports a somewhat conventional regex syntax
52
+ for pattern usage within <a href="lpeg.html">LPeg</a>.
53
+ </p>
54
+
55
+ <p>
56
+ The next table summarizes <code>re</code>'s syntax.
57
+ A <code>p</code> represents an arbitrary pattern;
58
+ <code>num</code> represents a number (<code>[0-9]+</code>);
59
+ <code>name</code> represents an identifier
60
+ (<code>[a-zA-Z][a-zA-Z0-9_]*</code>).
61
+ Constructions are listed in order of decreasing precedence.
62
+ <table border="1">
63
+ <tbody><tr><td><b>Syntax</b></td><td><b>Description</b></td></tr>
64
+ <tr><td><code>( p )</code></td> <td>grouping</td></tr>
65
+ <tr><td><code>'string'</code></td> <td>literal string</td></tr>
66
+ <tr><td><code>"string"</code></td> <td>literal string</td></tr>
67
+ <tr><td><code>[class]</code></td> <td>character class</td></tr>
68
+ <tr><td><code>.</code></td> <td>any character</td></tr>
69
+ <tr><td><code>%name</code></td>
70
+ <td>pattern <code>defs[name]</code> or a pre-defined pattern</td></tr>
71
+ <tr><td><code>name</code></td><td>non terminal</td></tr>
72
+ <tr><td><code>&lt;name&gt;</code></td><td>non terminal</td></tr>
73
+ <tr><td><code>{}</code></td> <td>position capture</td></tr>
74
+ <tr><td><code>{ p }</code></td> <td>simple capture</td></tr>
75
+ <tr><td><code>{: p :}</code></td> <td>anonymous group capture</td></tr>
76
+ <tr><td><code>{:name: p :}</code></td> <td>named group capture</td></tr>
77
+ <tr><td><code>{~ p ~}</code></td> <td>substitution capture</td></tr>
78
+ <tr><td><code>{| p |}</code></td> <td>table capture</td></tr>
79
+ <tr><td><code>=name</code></td> <td>back reference
80
+ </td></tr>
81
+ <tr><td><code>p ?</code></td> <td>optional match</td></tr>
82
+ <tr><td><code>p *</code></td> <td>zero or more repetitions</td></tr>
83
+ <tr><td><code>p +</code></td> <td>one or more repetitions</td></tr>
84
+ <tr><td><code>p^num</code></td> <td>exactly <code>n</code> repetitions</td></tr>
85
+ <tr><td><code>p^+num</code></td>
86
+ <td>at least <code>n</code> repetitions</td></tr>
87
+ <tr><td><code>p^-num</code></td>
88
+ <td>at most <code>n</code> repetitions</td></tr>
89
+ <tr><td><code>p -&gt; 'string'</code></td> <td>string capture</td></tr>
90
+ <tr><td><code>p -&gt; "string"</code></td> <td>string capture</td></tr>
91
+ <tr><td><code>p -&gt; num</code></td> <td>numbered capture</td></tr>
92
+ <tr><td><code>p -&gt; name</code></td> <td>function/query/string capture
93
+ equivalent to <code>p / defs[name]</code></td></tr>
94
+ <tr><td><code>p =&gt; name</code></td> <td>match-time capture
95
+ equivalent to <code>lpeg.Cmt(p, defs[name])</code></td></tr>
96
+ <tr><td><code>& p</code></td> <td>and predicate</td></tr>
97
+ <tr><td><code>! p</code></td> <td>not predicate</td></tr>
98
+ <tr><td><code>p1 p2</code></td> <td>concatenation</td></tr>
99
+ <tr><td><code>p1 / p2</code></td> <td>ordered choice</td></tr>
100
+ <tr><td>(<code>name &lt;- p</code>)<sup>+</sup></td> <td>grammar</td></tr>
101
+ </tbody></table>
102
+ <p>
103
+ Any space appearing in a syntax description can be
104
+ replaced by zero or more space characters and Lua-style comments
105
+ (<code>--</code> until end of line).
106
+ </p>
107
+
108
+ <p>
109
+ Character classes define sets of characters.
110
+ An initial <code>^</code> complements the resulting set.
111
+ A range <em>x</em><code>-</code><em>y</em> includes in the set
112
+ all characters with codes between the codes of <em>x</em> and <em>y</em>.
113
+ A pre-defined class <code>%</code><em>name</em> includes all
114
+ characters of that class.
115
+ A simple character includes itself in the set.
116
+ The only special characters inside a class are <code>^</code>
117
+ (special only if it is the first character);
118
+ <code>]</code>
119
+ (can be included in the set as the first character,
120
+ after the optional <code>^</code>);
121
+ <code>%</code> (special only if followed by a letter);
122
+ and <code>-</code>
123
+ (can be included in the set as the first or the last character).
124
+ </p>
125
+
126
+ <p>
127
+ Currently the pre-defined classes are similar to those from the
128
+ Lua's string library
129
+ (<code>%a</code> for letters,
130
+ <code>%A</code> for non letters, etc.).
131
+ There is also a class <code>%nl</code>
132
+ containing only the newline character,
133
+ which is particularly handy for grammars written inside long strings,
134
+ as long strings do not interpret escape sequences like <code>\n</code>.
135
+ </p>
136
+
137
+
138
+ <h2><a name="func">Functions</a></h2>
139
+
140
+ <h3><code>re.compile (string, [, defs])</code></h3>
141
+ <p>
142
+ Compiles the given string and
143
+ returns an equivalent LPeg pattern.
144
+ The given string may define either an expression or a grammar.
145
+ The optional <code>defs</code> table provides extra Lua values
146
+ to be used by the pattern.
147
+ </p>
148
+
149
+ <h3><code>re.find (subject, pattern [, init])</code></h3>
150
+ <p>
151
+ Searches the given pattern in the given subject.
152
+ If it finds a match,
153
+ returns the index where this occurrence starts and
154
+ the index where it ends.
155
+ Otherwise, returns nil.
156
+ </p>
157
+
158
+ <p>
159
+ An optional numeric argument <code>init</code> makes the search
160
+ starts at that position in the subject string.
161
+ As usual in Lua libraries,
162
+ a negative value counts from the end.
163
+ </p>
164
+
165
+ <h3><code>re.gsub (subject, pattern, replacement)</code></h3>
166
+ <p>
167
+ Does a <em>global substitution</em>,
168
+ replacing all occurrences of <code>pattern</code>
169
+ in the given <code>subject</code> by <code>replacement</code>.
170
+
171
+ <h3><code>re.match (subject, pattern)</code></h3>
172
+ <p>
173
+ Matches the given pattern against the given subject,
174
+ returning all captures.
175
+ </p>
176
+
177
+ <h3><code>re.updatelocale ()</code></h3>
178
+ <p>
179
+ Updates the pre-defined character classes to the current locale.
180
+ </p>
181
+
182
+
183
+ <h2><a name="ex">Some Examples</a></h2>
184
+
185
+ <h3>A complete simple program</h3>
186
+ <p>
187
+ The next code shows a simple complete Lua program using
188
+ the <code>re</code> module:
189
+ </p>
190
+ <pre class="example">
191
+ local re = require"re"
192
+
193
+ -- find the position of the first numeral in a string
194
+ print(re.find("the number 423 is odd", "[0-9]+")) --&gt; 12 14
195
+
196
+ -- returns all words in a string
197
+ print(re.match("the number 423 is odd", "({%a+} / .)*"))
198
+ --&gt; the number is odd
199
+
200
+ -- returns the first numeral in a string
201
+ print(re.match("the number 423 is odd", "s <- {%d+} / . s"))
202
+ --&gt; 423
203
+
204
+ print(re.gsub("hello World", "[aeiou]", "."))
205
+ --&gt; h.ll. W.rld
206
+ </pre>
207
+
208
+
209
+ <h3>Balanced parentheses</h3>
210
+ <p>
211
+ The following call will produce the same pattern produced by the
212
+ Lua expression in the
213
+ <a href="lpeg.html#balanced">balanced parentheses</a> example:
214
+ </p>
215
+ <pre class="example">
216
+ b = re.compile[[ balanced &lt;- "(" ([^()] / balanced)* ")" ]]
217
+ </pre>
218
+
219
+ <h3>String reversal</h3>
220
+ <p>
221
+ The next example reverses a string:
222
+ </p>
223
+ <pre class="example">
224
+ rev = re.compile[[ R &lt;- (!.) -&gt; '' / ({.} R) -&gt; '%2%1']]
225
+ print(rev:match"0123456789") --&gt; 9876543210
226
+ </pre>
227
+
228
+ <h3>CSV decoder</h3>
229
+ <p>
230
+ The next example replicates the <a href="lpeg.html#CSV">CSV decoder</a>:
231
+ </p>
232
+ <pre class="example">
233
+ record = re.compile[[
234
+ record &lt;- {| field (',' field)* |} (%nl / !.)
235
+ field &lt;- escaped / nonescaped
236
+ nonescaped &lt;- { [^,"%nl]* }
237
+ escaped &lt;- '"' {~ ([^"] / '""' -&gt; '"')* ~} '"'
238
+ ]]
239
+ </pre>
240
+
241
+ <h3>Lua's long strings</h3>
242
+ <p>
243
+ The next example matches Lua long strings:
244
+ </p>
245
+ <pre class="example">
246
+ c = re.compile([[
247
+ longstring &lt;- ('[' {:eq: '='* :} '[' close)
248
+ close &lt;- ']' =eq ']' / . close
249
+ ]])
250
+
251
+ print(c:match'[==[]]===]]]]==]===[]') --&gt; 17
252
+ </pre>
253
+
254
+ <h3>Abstract Syntax Trees</h3>
255
+ <p>
256
+ This example shows a simple way to build an
257
+ abstract syntax tree (AST) for a given grammar.
258
+ To keep our example simple,
259
+ let us consider the following grammar
260
+ for lists of names:
261
+ </p>
262
+ <pre class="example">
263
+ p = re.compile[[
264
+ listname &lt;- (name s)*
265
+ name &lt;- [a-z][a-z]*
266
+ s &lt;- %s*
267
+ ]]
268
+ </pre>
269
+ <p>
270
+ Now, we will add captures to build a corresponding AST.
271
+ As a first step, the pattern will build a table to
272
+ represent each non terminal;
273
+ terminals will be represented by their corresponding strings:
274
+ </p>
275
+ <pre class="example">
276
+ c = re.compile[[
277
+ listname &lt;- {| (name s)* |}
278
+ name &lt;- {| {[a-z][a-z]*} |}
279
+ s &lt;- %s*
280
+ ]]
281
+ </pre>
282
+ <p>
283
+ Now, a match against <code>"hi hello bye"</code>
284
+ results in the table
285
+ <code>{{"hi"}, {"hello"}, {"bye"}}</code>.
286
+ </p>
287
+ <p>
288
+ For such a simple grammar,
289
+ this AST is more than enough;
290
+ actually, the tables around each single name
291
+ are already overkilling.
292
+ More complex grammars,
293
+ however, may need some more structure.
294
+ Specifically,
295
+ it would be useful if each table had
296
+ a <code>tag</code> field telling what non terminal
297
+ that table represents.
298
+ We can add such a tag using
299
+ <a href="lpeg.html/#cap-g">named group captures</a>:
300
+ </p>
301
+ <pre class="example">
302
+ x = re.compile[[
303
+ listname <- {| {:tag: '' -> 'list':} (name s)* |}
304
+ name <- {| {:tag: '' -> 'id':} {[a-z][a-z]*} |}
305
+ s <- ' '*
306
+ ]]
307
+ </pre>
308
+ <p>
309
+ With these group captures,
310
+ a match against <code>"hi hello bye"</code>
311
+ results in the following table:
312
+ </p>
313
+ <pre class="example">
314
+ {tag="list",
315
+ {tag="id", "hi"},
316
+ {tag="id", "hello"},
317
+ {tag="id", "bye"}
318
+ }
319
+ </pre>
320
+
321
+
322
+ <h3>Indented blocks</h3>
323
+ <p>
324
+ This example breaks indented blocks into tables,
325
+ respecting the indentation:
326
+ </p>
327
+ <pre class="example">
328
+ p = re.compile[[
329
+ block &lt;- {| {:ident:' '*:} line
330
+ ((=ident !' ' line) / &(=ident ' ') block)* |}
331
+ line &lt;- {[^%nl]*} %nl
332
+ ]]
333
+ </pre>
334
+ <p>
335
+ As an example,
336
+ consider the following text:
337
+ </p>
338
+ <pre class="example">
339
+ t = p:match[[
340
+ first line
341
+ subline 1
342
+ subline 2
343
+ second line
344
+ third line
345
+ subline 3.1
346
+ subline 3.1.1
347
+ subline 3.2
348
+ ]]
349
+ </pre>
350
+ <p>
351
+ The resulting table <code>t</code> will be like this:
352
+ </p>
353
+ <pre class="example">
354
+ {'first line'; {'subline 1'; 'subline 2'; ident = ' '};
355
+ 'second line';
356
+ 'third line'; { 'subline 3.1'; {'subline 3.1.1'; ident = ' '};
357
+ 'subline 3.2'; ident = ' '};
358
+ ident = ''}
359
+ </pre>
360
+
361
+ <h3>Macro expander</h3>
362
+ <p>
363
+ This example implements a simple macro expander.
364
+ Macros must be defined as part of the pattern,
365
+ following some simple rules:
366
+ </p>
367
+ <pre class="example">
368
+ p = re.compile[[
369
+ text &lt;- {~ item* ~}
370
+ item &lt;- macro / [^()] / '(' item* ')'
371
+ arg &lt;- ' '* {~ (!',' item)* ~}
372
+ args &lt;- '(' arg (',' arg)* ')'
373
+ -- now we define some macros
374
+ macro &lt;- ('apply' args) -&gt; '%1(%2)'
375
+ / ('add' args) -&gt; '%1 + %2'
376
+ / ('mul' args) -&gt; '%1 * %2'
377
+ ]]
378
+
379
+ print(p:match"add(mul(a,b), apply(f,x))") --&gt; a * b + f(x)
380
+ </pre>
381
+ <p>
382
+ A <code>text</code> is a sequence of items,
383
+ wherein we apply a substitution capture to expand any macros.
384
+ An <code>item</code> is either a macro,
385
+ any character different from parentheses,
386
+ or a parenthesized expression.
387
+ A macro argument (<code>arg</code>) is a sequence
388
+ of items different from a comma.
389
+ (Note that a comma may appear inside an item,
390
+ e.g., inside a parenthesized expression.)
391
+ Again we do a substitution capture to expand any macro
392
+ in the argument before expanding the outer macro.
393
+ <code>args</code> is a list of arguments separated by commas.
394
+ Finally we define the macros.
395
+ Each macro is a string substitution;
396
+ it replaces the macro name and its arguments by its corresponding string,
397
+ with each <code>%</code><em>n</em> replaced by the <em>n</em>-th argument.
398
+ </p>
399
+
400
+ <h3>Patterns</h3>
401
+ <p>
402
+ This example shows the complete syntax
403
+ of patterns accepted by <code>re</code>.
404
+ </p>
405
+ <pre class="example">
406
+ p = [=[
407
+
408
+ pattern &lt;- exp !.
409
+ exp &lt;- S (alternative / grammar)
410
+
411
+ alternative &lt;- seq ('/' S seq)*
412
+ seq &lt;- prefix*
413
+ prefix &lt;- '&amp;' S prefix / '!' S prefix / suffix
414
+ suffix &lt;- primary S (([+*?]
415
+ / '^' [+-]? num
416
+ / '-&gt;' S (string / '{}' / name)
417
+ / '=&gt;' S name) S)*
418
+
419
+ primary &lt;- '(' exp ')' / string / class / defined
420
+ / '{:' (name ':')? exp ':}'
421
+ / '=' name
422
+ / '{}'
423
+ / '{~' exp '~}'
424
+ / '{' exp '}'
425
+ / '.'
426
+ / name S !arrow
427
+ / '&lt;' name '&gt;' -- old-style non terminals
428
+
429
+ grammar &lt;- definition+
430
+ definition &lt;- name S arrow exp
431
+
432
+ class &lt;- '[' '^'? item (!']' item)* ']'
433
+ item &lt;- defined / range / .
434
+ range &lt;- . '-' [^]]
435
+
436
+ S &lt;- (%s / '--' [^%nl]*)* -- spaces and comments
437
+ name &lt;- [A-Za-z][A-Za-z0-9_]*
438
+ arrow &lt;- '&lt;-'
439
+ num &lt;- [0-9]+
440
+ string &lt;- '"' [^"]* '"' / "'" [^']* "'"
441
+ defined &lt;- '%' name
442
+
443
+ ]=]
444
+
445
+ print(re.match(p, p)) -- a self description must match itself
446
+ </pre>
447
+
448
+
449
+
450
+ <h2><a name="license">License</a></h2>
451
+
452
+ <p>
453
+ Copyright &copy; 2008-2010 Lua.org, PUC-Rio.
454
+ </p>
455
+ <p>
456
+ Permission is hereby granted, free of charge,
457
+ to any person obtaining a copy of this software and
458
+ associated documentation files (the "Software"),
459
+ to deal in the Software without restriction,
460
+ including without limitation the rights to use,
461
+ copy, modify, merge, publish, distribute, sublicense,
462
+ and/or sell copies of the Software,
463
+ and to permit persons to whom the Software is
464
+ furnished to do so,
465
+ subject to the following conditions:
466
+ </p>
467
+
468
+ <p>
469
+ The above copyright notice and this permission notice
470
+ shall be included in all copies or substantial portions of the Software.
471
+ </p>
472
+
473
+ <p>
474
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
475
+ EXPRESS OR IMPLIED,
476
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
477
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
478
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
479
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
480
+ TORT OR OTHERWISE, ARISING FROM,
481
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
482
+ THE SOFTWARE.
483
+ </p>
484
+
485
+ </div> <!-- id="content" -->
486
+
487
+ </div> <!-- id="main" -->
488
+
489
+ <div id="about">
490
+ <p><small>
491
+ $Id: re.html,v 1.21 2013/03/28 20:43:30 roberto Exp $
492
+ </small></p>
493
+ </div> <!-- id="about" -->
494
+
495
+ </div> <!-- id="container" -->
496
+
497
+ </body>
498
+ </html>