racc 1.4.14 → 1.4.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/Manifest.txt +50 -0
  3. data/ext/racc/com/headius/racc/Cparse.java +66 -23
  4. data/ext/racc/cparse.c +1 -1
  5. data/ext/racc/depend +1 -1
  6. data/lib/racc/info.rb +2 -2
  7. data/test/assets/bibtex.y +141 -0
  8. data/test/assets/cadenza.y +170 -0
  9. data/test/assets/cast.y +926 -0
  10. data/test/assets/csspool.y +729 -0
  11. data/test/assets/edtf.y +583 -0
  12. data/test/assets/huia.y +318 -0
  13. data/test/assets/journey.y +47 -0
  14. data/test/assets/liquor.y +313 -0
  15. data/test/assets/machete.y +423 -0
  16. data/test/assets/macruby.y +2197 -0
  17. data/test/assets/mediacloth.y +599 -0
  18. data/test/assets/mof.y +649 -0
  19. data/test/assets/namae.y +302 -0
  20. data/test/assets/nasl.y +626 -0
  21. data/test/assets/nokogiri-css.y +255 -0
  22. data/test/assets/opal.y +1807 -0
  23. data/test/assets/php_serialization.y +98 -0
  24. data/test/assets/rdblockparser.y +576 -0
  25. data/test/assets/rdinlineparser.y +561 -0
  26. data/test/assets/riml.y +665 -0
  27. data/test/assets/ruby18.y +1943 -0
  28. data/test/assets/ruby19.y +2174 -0
  29. data/test/assets/ruby20.y +2350 -0
  30. data/test/assets/ruby21.y +2359 -0
  31. data/test/assets/ruby22.y +2381 -0
  32. data/test/assets/tp_plus.y +622 -0
  33. data/test/assets/twowaysql.y +278 -0
  34. data/test/helper.rb +31 -15
  35. data/test/regress/bibtex +474 -0
  36. data/test/regress/cadenza +796 -0
  37. data/test/regress/cast +3425 -0
  38. data/test/regress/csspool +2318 -0
  39. data/test/regress/edtf +1794 -0
  40. data/test/regress/huia +1392 -0
  41. data/test/regress/journey +222 -0
  42. data/test/regress/liquor +885 -0
  43. data/test/regress/machete +833 -0
  44. data/test/regress/mediacloth +1463 -0
  45. data/test/regress/mof +1368 -0
  46. data/test/regress/namae +634 -0
  47. data/test/regress/nasl +2058 -0
  48. data/test/regress/nokogiri-css +836 -0
  49. data/test/regress/opal +6429 -0
  50. data/test/regress/php_serialization +336 -0
  51. data/test/regress/rdblockparser +1061 -0
  52. data/test/regress/rdinlineparser +1243 -0
  53. data/test/regress/riml +3297 -0
  54. data/test/regress/ruby18 +6351 -0
  55. data/test/regress/ruby22 +7456 -0
  56. data/test/regress/tp_plus +1933 -0
  57. data/test/regress/twowaysql +556 -0
  58. data/test/test_racc_command.rb +177 -0
  59. metadata +75 -20
@@ -0,0 +1,302 @@
1
+ # -*- ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ # Copyright (C) 2012 President and Fellows of Harvard College
5
+ # Copyright (C) 2013-2014 Sylvester Keil
6
+ #
7
+ # Redistribution and use in source and binary forms, with or without
8
+ # modification, are permitted provided that the following conditions are met:
9
+ #
10
+ # 1. Redistributions of source code must retain the above copyright notice,
11
+ # this list of conditions and the following disclaimer.
12
+ #
13
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
14
+ # this list of conditions and the following disclaimer in the documentation
15
+ # and/or other materials provided with the distribution.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR
18
+ # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19
+ # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20
+ # EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
21
+ # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22
+ # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24
+ # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
+ # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #
28
+ # The views and conclusions contained in the software and documentation are
29
+ # those of the authors and should not be interpreted as representing official
30
+ # policies, either expressed or implied, of the copyright holder.
31
+
32
+ class Namae::Parser
33
+
34
+ token COMMA UWORD LWORD PWORD NICK AND APPELLATION TITLE SUFFIX
35
+
36
+ expect 0
37
+
38
+ rule
39
+
40
+ names : { result = [] }
41
+ | name { result = [val[0]] }
42
+ | names AND name { result = val[0] << val[2] }
43
+
44
+ name : word { result = Name.new(:given => val[0]) }
45
+ | display_order
46
+ | honorific word { result = val[0].merge(:family => val[1]) }
47
+ | honorific display_order { result = val[1].merge(val[0]) }
48
+ | sort_order
49
+
50
+ honorific : APPELLATION { result = Name.new(:appellation => val[0]) }
51
+ | TITLE { result = Name.new(:title => val[0]) }
52
+
53
+ display_order : u_words word opt_suffices opt_titles
54
+ {
55
+ result = Name.new(:given => val[0], :family => val[1],
56
+ :suffix => val[2], :title => val[3])
57
+ }
58
+ | u_words NICK last opt_suffices opt_titles
59
+ {
60
+ result = Name.new(:given => val[0], :nick => val[1],
61
+ :family => val[2], :suffix => val[3], :title => val[4])
62
+ }
63
+ | u_words NICK von last opt_suffices opt_titles
64
+ {
65
+ result = Name.new(:given => val[0], :nick => val[1],
66
+ :particle => val[2], :family => val[3],
67
+ :suffix => val[4], :title => val[5])
68
+ }
69
+ | u_words von last
70
+ {
71
+ result = Name.new(:given => val[0], :particle => val[1],
72
+ :family => val[2])
73
+ }
74
+ | von last
75
+ {
76
+ result = Name.new(:particle => val[0], :family => val[1])
77
+ }
78
+
79
+ sort_order : last COMMA first
80
+ {
81
+ result = Name.new({ :family => val[0], :suffix => val[2][0],
82
+ :given => val[2][1] }, !!val[2][0])
83
+ }
84
+ | von last COMMA first
85
+ {
86
+ result = Name.new({ :particle => val[0], :family => val[1],
87
+ :suffix => val[3][0], :given => val[3][1] }, !!val[3][0])
88
+ }
89
+ | u_words von last COMMA first
90
+ {
91
+ result = Name.new({ :particle => val[0,2].join(' '), :family => val[2],
92
+ :suffix => val[4][0], :given => val[4][1] }, !!val[4][0])
93
+ }
94
+ ;
95
+
96
+ von : LWORD
97
+ | von LWORD { result = val.join(' ') }
98
+ | von u_words LWORD { result = val.join(' ') }
99
+
100
+ last : LWORD | u_words
101
+
102
+ first : opt_words { result = [nil,val[0]] }
103
+ | words opt_comma suffices { result = [val[2],val[0]] }
104
+ | suffices { result = [val[0],nil] }
105
+ | suffices COMMA words { result = [val[0],val[2]] }
106
+
107
+ u_words : u_word
108
+ | u_words u_word { result = val.join(' ') }
109
+
110
+ u_word : UWORD | PWORD
111
+
112
+ words : word
113
+ | words word { result = val.join(' ') }
114
+
115
+ opt_comma : /* empty */ | COMMA
116
+ opt_words : /* empty */ | words
117
+
118
+ word : LWORD | UWORD | PWORD
119
+
120
+ opt_suffices : /* empty */ | suffices
121
+
122
+ suffices : SUFFIX
123
+ | suffices SUFFIX { result = val.join(' ') }
124
+
125
+ opt_titles : /* empty */ | titles
126
+
127
+ titles : TITLE
128
+ | titles TITLE { result = val.join(' ') }
129
+
130
+ ---- header
131
+ require 'singleton'
132
+ require 'strscan'
133
+
134
+ ---- inner
135
+
136
+ include Singleton
137
+
138
+ attr_reader :options, :input
139
+
140
+ def initialize
141
+ @input, @options = StringScanner.new(''), {
142
+ :debug => false,
143
+ :prefer_comma_as_separator => false,
144
+ :comma => ',',
145
+ :stops => ',;',
146
+ :separator => /\s*(\band\b|\&|;)\s*/i,
147
+ :title => /\s*\b(sir|lord|count(ess)?|(gen|adm|col|maj|capt|cmdr|lt|sgt|cpl|pvt|prof|dr|md|ph\.?d)\.?)(\s+|$)/i,
148
+ :suffix => /\s*\b(JR|Jr|jr|SR|Sr|sr|[IVX]{2,})(\.|\b)/,
149
+ :appellation => /\s*\b((mrs?|ms|fr|hr)\.?|miss|herr|frau)(\s+|$)/i
150
+ }
151
+ end
152
+
153
+ def debug?
154
+ options[:debug] || ENV['DEBUG']
155
+ end
156
+
157
+ def separator
158
+ options[:separator]
159
+ end
160
+
161
+ def comma
162
+ options[:comma]
163
+ end
164
+
165
+ def stops
166
+ options[:stops]
167
+ end
168
+
169
+ def title
170
+ options[:title]
171
+ end
172
+
173
+ def suffix
174
+ options[:suffix]
175
+ end
176
+
177
+ def appellation
178
+ options[:appellation]
179
+ end
180
+
181
+ def prefer_comma_as_separator?
182
+ options[:prefer_comma_as_separator]
183
+ end
184
+
185
+ def parse(input)
186
+ parse!(input)
187
+ rescue => e
188
+ warn e.message if debug?
189
+ []
190
+ end
191
+
192
+ def parse!(string)
193
+ input.string = normalize(string)
194
+ reset
195
+ do_parse
196
+ end
197
+
198
+ def normalize(string)
199
+ string = string.strip
200
+ string
201
+ end
202
+
203
+ def reset
204
+ @commas, @words, @initials, @suffices, @yydebug = 0, 0, 0, 0, debug?
205
+ self
206
+ end
207
+
208
+ private
209
+
210
+ def stack
211
+ @vstack || @racc_vstack || []
212
+ end
213
+
214
+ def last_token
215
+ stack[-1]
216
+ end
217
+
218
+ def consume_separator
219
+ return next_token if seen_separator?
220
+ @commas, @words, @initials, @suffices = 0, 0, 0, 0
221
+ [:AND, :AND]
222
+ end
223
+
224
+ def consume_comma
225
+ @commas += 1
226
+ [:COMMA, :COMMA]
227
+ end
228
+
229
+ def consume_word(type, word)
230
+ @words += 1
231
+
232
+ case type
233
+ when :UWORD
234
+ @initials += 1 if word =~ /^[[:upper:]]+\b/
235
+ when :SUFFIX
236
+ @suffices += 1
237
+ end
238
+
239
+ [type, word]
240
+ end
241
+
242
+ def seen_separator?
243
+ !stack.empty? && last_token == :AND
244
+ end
245
+
246
+ def suffix?
247
+ !@suffices.zero? || will_see_suffix?
248
+ end
249
+
250
+ def will_see_suffix?
251
+ input.peek(8).to_s.strip.split(/\s+/)[0] =~ suffix
252
+ end
253
+
254
+ def will_see_initial?
255
+ input.peek(6).to_s.strip.split(/\s+/)[0] =~ /^[[:upper:]]+\b/
256
+ end
257
+
258
+ def seen_full_name?
259
+ prefer_comma_as_separator? && @words > 1 &&
260
+ (@initials > 0 || !will_see_initial?) && !will_see_suffix?
261
+ end
262
+
263
+ def next_token
264
+ case
265
+ when input.nil?, input.eos?
266
+ nil
267
+ when input.scan(separator)
268
+ consume_separator
269
+ when input.scan(/\s*#{comma}\s*/)
270
+ if @commas.zero? && !seen_full_name? || @commas == 1 && suffix?
271
+ consume_comma
272
+ else
273
+ consume_separator
274
+ end
275
+ when input.scan(/\s+/)
276
+ next_token
277
+ when input.scan(title)
278
+ consume_word(:TITLE, input.matched.strip)
279
+ when input.scan(suffix)
280
+ consume_word(:SUFFIX, input.matched.strip)
281
+ when input.scan(appellation)
282
+ [:APPELLATION, input.matched.strip]
283
+ when input.scan(/((\\\w+)?\{[^\}]*\})*[[:upper:]][^\s#{stops}]*/)
284
+ consume_word(:UWORD, input.matched)
285
+ when input.scan(/((\\\w+)?\{[^\}]*\})*[[:lower:]][^\s#{stops}]*/)
286
+ consume_word(:LWORD, input.matched)
287
+ when input.scan(/(\\\w+)?\{[^\}]*\}[^\s#{stops}]*/)
288
+ consume_word(:PWORD, input.matched)
289
+ when input.scan(/('[^'\n]+')|("[^"\n]+")/)
290
+ consume_word(:NICK, input.matched[1...-1])
291
+ else
292
+ raise ArgumentError,
293
+ "Failed to parse name #{input.string.inspect}: unmatched data at offset #{input.pos}"
294
+ end
295
+ end
296
+
297
+ def on_error(tid, value, stack)
298
+ raise ArgumentError,
299
+ "Failed to parse name: unexpected '#{value}' at #{stack.inspect}"
300
+ end
301
+
302
+ # -*- racc -*-
@@ -0,0 +1,626 @@
1
+ ################################################################################
2
+ # Copyright (c) 2011-2014, Tenable Network Security
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # 1. Redistributions of source code must retain the above copyright notice, this
9
+ # list of conditions and the following disclaimer.
10
+ #
11
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ ################################################################################
26
+
27
+ class Nasl::Grammar
28
+
29
+ preclow
30
+ right ASS_EQ ADD_EQ SUB_EQ MUL_EQ DIV_EQ MOD_EQ SLL_EQ SRA_EQ SRL_EQ
31
+ left OR
32
+ left AND
33
+ left CMP_LT CMP_GT CMP_EQ CMP_NE CMP_GE CMP_LE SUBSTR_EQ SUBSTR_NE REGEX_EQ REGEX_NE
34
+ left BIT_OR
35
+ left BIT_XOR
36
+ left AMPERSAND
37
+ left BIT_SRA BIT_SRL BIT_SLL
38
+ left ADD SUB
39
+ left MUL DIV MOD
40
+ right NOT
41
+ right UMINUS BIT_NOT
42
+ right EXP
43
+ right INCR DECR
44
+ prechigh
45
+
46
+ # Tell the parser generator that we don't wish to use the result variable in the
47
+ # action section of rules. Instead, the result of the rule will be the value of
48
+ # evaluating the action block.
49
+ options no_result_var
50
+
51
+ # Tell the parser generator that we expect one shift/reduce conflict due to the
52
+ # well-known dangling else problem. We could make the grammar solve this
53
+ # problem, but this is how the NASL YACC file solves it, so we'll follow suit.
54
+ expect 1
55
+
56
+ rule
57
+ ##############################################################################
58
+ # Aggregate Statements
59
+ ##############################################################################
60
+
61
+ start : roots
62
+ { val[0] }
63
+ | /* Blank */
64
+ { [] }
65
+ ;
66
+
67
+ roots : root roots
68
+ { [val[0]] + val[1] }
69
+ | root
70
+ { [val[0]] }
71
+ ;
72
+
73
+ root : COMMENT export
74
+ { c(*val) }
75
+ | export
76
+ { val[0] }
77
+ | COMMENT function
78
+ { c(*val) }
79
+ | function
80
+ { val[0] }
81
+ | statement
82
+ { val[0] }
83
+ ;
84
+
85
+ statement : simple
86
+ { val[0] }
87
+ | compound
88
+ { val[0] }
89
+ ;
90
+
91
+ ##############################################################################
92
+ # Root Statements
93
+ ##############################################################################
94
+
95
+ export : EXPORT function
96
+ { n(:Export, *val) }
97
+ ;
98
+
99
+ function : FUNCTION ident LPAREN params RPAREN block
100
+ { n(:Function, *val) }
101
+ | FUNCTION ident LPAREN RPAREN block
102
+ { n(:Function, *val) }
103
+ ;
104
+
105
+ simple : assign
106
+ { val[0] }
107
+ | break
108
+ { val[0] }
109
+ | call
110
+ { val[0] }
111
+ | continue
112
+ { val[0] }
113
+ | decr
114
+ { val[0] }
115
+ | empty
116
+ { val[0] }
117
+ | COMMENT global
118
+ { c(*val) }
119
+ | global
120
+ { val[0] }
121
+ | import
122
+ { val[0] }
123
+ | include
124
+ { val[0] }
125
+ | incr
126
+ { val[0] }
127
+ | local
128
+ { val[0] }
129
+ | rep
130
+ { val[0] }
131
+ | return
132
+ { val[0] }
133
+ ;
134
+
135
+ compound : block
136
+ { val[0] }
137
+ | for
138
+ { val[0] }
139
+ | foreach
140
+ { val[0] }
141
+ | if
142
+ { val[0] }
143
+ | repeat
144
+ { val[0] }
145
+ | while
146
+ { val[0] }
147
+ ;
148
+
149
+ ##############################################################################
150
+ # Simple Statements
151
+ ##############################################################################
152
+
153
+ assign : assign_exp SEMICOLON
154
+ { val[0] }
155
+ ;
156
+
157
+ break : BREAK SEMICOLON
158
+ { n(:Break, *val) }
159
+ ;
160
+
161
+ call : call_exp SEMICOLON
162
+ { val[0] }
163
+ ;
164
+
165
+ continue : CONTINUE SEMICOLON
166
+ { n(:Continue, *val) }
167
+ ;
168
+
169
+ decr : decr_exp SEMICOLON
170
+ { val[0] }
171
+ ;
172
+
173
+ empty : SEMICOLON
174
+ { n(:Empty, *val) }
175
+ ;
176
+
177
+ global : GLOBAL var_decls SEMICOLON
178
+ { n(:Global, *val) }
179
+ ;
180
+
181
+ incr : incr_exp SEMICOLON
182
+ { val[0] }
183
+ ;
184
+
185
+ import : IMPORT LPAREN string RPAREN SEMICOLON
186
+ { n(:Import, *val) }
187
+ ;
188
+
189
+ include : INCLUDE LPAREN string RPAREN SEMICOLON
190
+ { n(:Include, *val) }
191
+ ;
192
+
193
+ local : LOCAL var_decls SEMICOLON
194
+ { n(:Local, *val) }
195
+ ;
196
+
197
+ rep : call_exp REP expr SEMICOLON
198
+ { n(:Repetition, *val[0..-1]) }
199
+ ;
200
+
201
+ return : RETURN expr SEMICOLON
202
+ { n(:Return, *val) }
203
+ | RETURN ref SEMICOLON
204
+ { n(:Return, *val) }
205
+ | RETURN SEMICOLON
206
+ { n(:Return, *val) }
207
+ ;
208
+
209
+ ##############################################################################
210
+ # Compound Statements
211
+ ##############################################################################
212
+
213
+ block : LBRACE statements RBRACE
214
+ { n(:Block, *val) }
215
+ | LBRACE RBRACE
216
+ { n(:Block, *val) }
217
+ ;
218
+
219
+ for : FOR LPAREN field SEMICOLON expr SEMICOLON field RPAREN statement
220
+ { n(:For, *val) }
221
+ ;
222
+
223
+ foreach : FOREACH ident LPAREN expr RPAREN statement
224
+ { n(:Foreach, val[0], val[1], val[3], val[5]) }
225
+ | FOREACH LPAREN ident IN expr RPAREN statement
226
+ { n(:Foreach, val[0], val[2], val[4], val[6]) }
227
+ ;
228
+
229
+ if : IF LPAREN expr RPAREN statement
230
+ { n(:If, *val) }
231
+ | IF LPAREN expr RPAREN statement ELSE statement
232
+ { n(:If, *val) }
233
+ ;
234
+
235
+ repeat : REPEAT statement UNTIL expr SEMICOLON
236
+ { n(:Repeat, *val) }
237
+ ;
238
+
239
+ while : WHILE LPAREN expr RPAREN statement
240
+ { n(:While, *val) }
241
+ ;
242
+
243
+ ##############################################################################
244
+ # Expressions
245
+ ##############################################################################
246
+
247
+ assign_exp : lval ASS_EQ expr
248
+ { n(:Assignment, *val) }
249
+ | lval ASS_EQ ref
250
+ { n(:Assignment, *val) }
251
+ | lval ADD_EQ expr
252
+ { n(:Assignment, *val) }
253
+ | lval SUB_EQ expr
254
+ { n(:Assignment, *val) }
255
+ | lval MUL_EQ expr
256
+ { n(:Assignment, *val) }
257
+ | lval DIV_EQ expr
258
+ { n(:Assignment, *val) }
259
+ | lval MOD_EQ expr
260
+ { n(:Assignment, *val) }
261
+ | lval SRL_EQ expr
262
+ { n(:Assignment, *val) }
263
+ | lval SRA_EQ expr
264
+ { n(:Assignment, *val) }
265
+ | lval SLL_EQ expr
266
+ { n(:Assignment, *val) }
267
+ ;
268
+
269
+ call_exp : lval LPAREN args RPAREN
270
+ { n(:Call, *val) }
271
+ | lval LPAREN RPAREN
272
+ { n(:Call, *val) }
273
+ ;
274
+
275
+ decr_exp : DECR lval
276
+ { n(:Decrement, val[0]) }
277
+ | lval DECR
278
+ { n(:Decrement, val[0]) }
279
+ ;
280
+
281
+ incr_exp : INCR lval
282
+ { n(:Increment, val[0]) }
283
+ | lval INCR
284
+ { n(:Increment, val[0]) }
285
+ ;
286
+
287
+ expr : LPAREN expr RPAREN
288
+ { n(:Expression, *val) }
289
+ | expr AND expr
290
+ { n(:Expression, *val) }
291
+ | NOT expr
292
+ { n(:Expression, *val) }
293
+ | expr OR expr
294
+ { n(:Expression, *val) }
295
+ | expr ADD expr
296
+ { n(:Expression, *val) }
297
+ | expr SUB expr
298
+ { n(:Expression, *val) }
299
+ | SUB expr =UMINUS
300
+ { n(:Expression, *val) }
301
+ | BIT_NOT expr
302
+ { n(:Expression, *val) }
303
+ | expr MUL expr
304
+ { n(:Expression, *val) }
305
+ | expr EXP expr
306
+ { n(:Expression, *val) }
307
+ | expr DIV expr
308
+ { n(:Expression, *val) }
309
+ | expr MOD expr
310
+ { n(:Expression, *val) }
311
+ | expr AMPERSAND expr
312
+ { n(:Expression, *val) }
313
+ | expr BIT_XOR expr
314
+ { n(:Expression, *val) }
315
+ | expr BIT_OR expr
316
+ { n(:Expression, *val) }
317
+ | expr BIT_SRA expr
318
+ { n(:Expression, *val) }
319
+ | expr BIT_SRL expr
320
+ { n(:Expression, *val) }
321
+ | expr BIT_SLL expr
322
+ { n(:Expression, *val) }
323
+ | incr_exp
324
+ { val[0] }
325
+ | decr_exp
326
+ { val[0] }
327
+ | expr SUBSTR_EQ expr
328
+ { n(:Expression, *val) }
329
+ | expr SUBSTR_NE expr
330
+ { n(:Expression, *val) }
331
+ | expr REGEX_EQ expr
332
+ { n(:Expression, *val) }
333
+ | expr REGEX_NE expr
334
+ { n(:Expression, *val) }
335
+ | expr CMP_LT expr
336
+ { n(:Expression, *val) }
337
+ | expr CMP_GT expr
338
+ { n(:Expression, *val) }
339
+ | expr CMP_EQ expr
340
+ { n(:Expression, *val) }
341
+ | expr CMP_NE expr
342
+ { n(:Expression, *val) }
343
+ | expr CMP_GE expr
344
+ { n(:Expression, *val) }
345
+ | expr CMP_LE expr
346
+ { n(:Expression, *val) }
347
+ | assign_exp
348
+ { val[0] }
349
+ | string
350
+ { val[0] }
351
+ | call_exp
352
+ { val[0] }
353
+ | lval
354
+ { val[0] }
355
+ | ip
356
+ { val[0] }
357
+ | int
358
+ { val[0] }
359
+ | undef
360
+ { val[0] }
361
+ | list_expr
362
+ { val[0] }
363
+ | array_expr
364
+ { val[0] }
365
+ ;
366
+
367
+ ##############################################################################
368
+ # Named Components
369
+ ##############################################################################
370
+
371
+ arg : ident COLON expr
372
+ { n(:Argument, *val) }
373
+ | ident COLON ref
374
+ { n(:Argument, *val) }
375
+ | expr
376
+ { n(:Argument, *val) }
377
+ | ref
378
+ { n(:Argument, *val) }
379
+ ;
380
+
381
+ kv_pair : string COLON expr
382
+ { n(:KeyValuePair, *val) }
383
+ | int COLON expr
384
+ { n(:KeyValuePair, *val) }
385
+ | ident COLON expr
386
+ { n(:KeyValuePair, *val) }
387
+ | string COLON ref
388
+ { n(:KeyValuePair, *val) }
389
+ | int COLON ref
390
+ { n(:KeyValuePair, *val) }
391
+ | ident COLON ref
392
+ { n(:KeyValuePair, *val) }
393
+ ;
394
+
395
+ kv_pairs : kv_pair COMMA kv_pairs
396
+ { [val[0]] + val[2] }
397
+ | kv_pair COMMA
398
+ { [val[0]] }
399
+ | kv_pair
400
+ { [val[0]] }
401
+ ;
402
+
403
+ lval : ident indexes
404
+ { n(:Lvalue, *val) }
405
+ | ident
406
+ { n(:Lvalue, *val) }
407
+ ;
408
+
409
+ ref : AT_SIGN ident
410
+ { n(:Reference, val[1]) }
411
+ ;
412
+
413
+ ##############################################################################
414
+ # Anonymous Components
415
+ ##############################################################################
416
+
417
+ args : arg COMMA args
418
+ { [val[0]] + val[2] }
419
+ | arg
420
+ { [val[0]] }
421
+ ;
422
+
423
+ array_expr : LBRACE kv_pairs RBRACE
424
+ { n(:Array, *val) }
425
+ | LBRACE RBRACE
426
+ { n(:Array, *val) }
427
+ ;
428
+
429
+ field : assign_exp
430
+ { val[0] }
431
+ | call_exp
432
+ { val[0] }
433
+ | decr_exp
434
+ { val[0] }
435
+ | incr_exp
436
+ { val[0] }
437
+ | /* Blank */
438
+ { nil }
439
+ ;
440
+
441
+ index : LBRACK expr RBRACK
442
+ { val[1] }
443
+ | PERIOD ident
444
+ { val[1] }
445
+ ;
446
+
447
+ indexes : index indexes
448
+ { [val[0]] + val[1] }
449
+ | index
450
+ { [val[0]] }
451
+ ;
452
+
453
+ list_elem : expr
454
+ { val[0] }
455
+ | ref
456
+ { val[0] }
457
+ ;
458
+
459
+ list_elems : list_elem COMMA list_elems
460
+ { [val[0]] + val[2] }
461
+ | list_elem
462
+ { [val[0]] }
463
+ ;
464
+
465
+ list_expr : LBRACK list_elems RBRACK
466
+ { n(:List, *val) }
467
+ | LBRACK RBRACK
468
+ { n(:List, *val) }
469
+ ;
470
+
471
+ param : AMPERSAND ident
472
+ { n(:Parameter, val[1], 'reference') }
473
+ | ident
474
+ { n(:Parameter, val[0], 'value') }
475
+ ;
476
+
477
+ params : param COMMA params
478
+ { [val[0]] + val[2] }
479
+ | param
480
+ { [val[0]] }
481
+ ;
482
+
483
+ statements : statement statements
484
+ { [val[0]] + val[1] }
485
+ | statement
486
+ { [val[0]] }
487
+ ;
488
+
489
+ var_decl : ident ASS_EQ expr
490
+ { n(:Assignment, *val) }
491
+ | ident ASS_EQ ref
492
+ { n(:Assignment, *val) }
493
+ | ident
494
+ { val[0] }
495
+ ;
496
+
497
+ var_decls : var_decl COMMA var_decls
498
+ { [val[0]] + val[2] }
499
+ | var_decl
500
+ { [val[0]] }
501
+ ;
502
+
503
+ ##############################################################################
504
+ # Literals
505
+ ##############################################################################
506
+
507
+ ident : IDENT
508
+ { n(:Identifier, *val) }
509
+ | REP
510
+ { n(:Identifier, *val) }
511
+ | IN
512
+ { n(:Identifier, *val) }
513
+ ;
514
+
515
+ int : INT_DEC
516
+ { n(:Integer, *val) }
517
+ | INT_HEX
518
+ { n(:Integer, *val) }
519
+ | INT_OCT
520
+ { n(:Integer, *val) }
521
+ | FALSE
522
+ { n(:Integer, *val) }
523
+ | TRUE
524
+ { n(:Integer, *val) }
525
+ ;
526
+
527
+ ip : int PERIOD int PERIOD int PERIOD int
528
+ { n(:Ip, *val) }
529
+
530
+ string : DATA
531
+ { n(:String, *val) }
532
+ | STRING
533
+ { n(:String, *val) }
534
+ ;
535
+
536
+ undef : UNDEF
537
+ { n(:Undefined, *val) }
538
+ ;
539
+ end
540
+
541
+ ---- header ----
542
+
543
+ require 'nasl/parser/tree'
544
+
545
+ require 'nasl/parser/argument'
546
+ require 'nasl/parser/array'
547
+ require 'nasl/parser/assigment'
548
+ require 'nasl/parser/block'
549
+ require 'nasl/parser/break'
550
+ require 'nasl/parser/call'
551
+ require 'nasl/parser/comment'
552
+ require 'nasl/parser/continue'
553
+ require 'nasl/parser/decrement'
554
+ require 'nasl/parser/empty'
555
+ require 'nasl/parser/export'
556
+ require 'nasl/parser/expression'
557
+ require 'nasl/parser/for'
558
+ require 'nasl/parser/foreach'
559
+ require 'nasl/parser/function'
560
+ require 'nasl/parser/global'
561
+ require 'nasl/parser/identifier'
562
+ require 'nasl/parser/if'
563
+ require 'nasl/parser/import'
564
+ require 'nasl/parser/include'
565
+ require 'nasl/parser/increment'
566
+ require 'nasl/parser/integer'
567
+ require 'nasl/parser/ip'
568
+ require 'nasl/parser/key_value_pair'
569
+ require 'nasl/parser/list'
570
+ require 'nasl/parser/local'
571
+ require 'nasl/parser/lvalue'
572
+ require 'nasl/parser/parameter'
573
+ require 'nasl/parser/reference'
574
+ require 'nasl/parser/repeat'
575
+ require 'nasl/parser/repetition'
576
+ require 'nasl/parser/return'
577
+ require 'nasl/parser/string'
578
+ require 'nasl/parser/undefined'
579
+ require 'nasl/parser/while'
580
+
581
+ ---- inner ----
582
+
583
+ def n(cls, *args)
584
+ begin
585
+ Nasl.const_get(cls).new(@tree, *args)
586
+ rescue
587
+ puts "An exception occurred during the creation of a #{cls} instance."
588
+ puts
589
+ puts "The arguments passed to the constructer were:"
590
+ puts args
591
+ puts
592
+ puts @tok.last.context
593
+ puts
594
+ raise
595
+ end
596
+ end
597
+
598
+ def c(*args)
599
+ n(:Comment, *args)
600
+ args[1]
601
+ end
602
+
603
+ def on_error(type, value, stack)
604
+ raise ParseException, "The language's grammar does not permit #{value.name} to appear here", value.context
605
+ end
606
+
607
+ def next_token
608
+ @tok = @tkz.get_token
609
+
610
+ if @first && @tok.first == :COMMENT
611
+ n(:Comment, @tok.last)
612
+ @tok = @tkz.get_token
613
+ end
614
+ @first = false
615
+
616
+ return @tok
617
+ end
618
+
619
+ def parse(env, code, path)
620
+ @first = true
621
+ @tree = Tree.new(env)
622
+ @tkz = Tokenizer.new(code, path)
623
+ @tree.concat(do_parse)
624
+ end
625
+
626
+ ---- footer ----