nasl 0.0.1

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 (72) hide show
  1. data/.gitignore +9 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +8 -0
  4. data/bin/nasl-parse +33 -0
  5. data/lib/nasl/cli.rb +94 -0
  6. data/lib/nasl/command.rb +96 -0
  7. data/lib/nasl/commands/benchmark.rb +55 -0
  8. data/lib/nasl/commands/parse.rb +55 -0
  9. data/lib/nasl/commands/test.rb +37 -0
  10. data/lib/nasl/commands/tokenize.rb +46 -0
  11. data/lib/nasl/commands/xml.rb +41 -0
  12. data/lib/nasl/context.rb +102 -0
  13. data/lib/nasl/grammar.racc +513 -0
  14. data/lib/nasl/grammar.tab.rb +1650 -0
  15. data/lib/nasl/parser/argument.rb +50 -0
  16. data/lib/nasl/parser/assigment.rb +45 -0
  17. data/lib/nasl/parser/block.rb +41 -0
  18. data/lib/nasl/parser/break.rb +32 -0
  19. data/lib/nasl/parser/call.rb +48 -0
  20. data/lib/nasl/parser/continue.rb +32 -0
  21. data/lib/nasl/parser/decrement.rb +48 -0
  22. data/lib/nasl/parser/empty.rb +32 -0
  23. data/lib/nasl/parser/export.rb +41 -0
  24. data/lib/nasl/parser/expression.rb +56 -0
  25. data/lib/nasl/parser/for.rb +47 -0
  26. data/lib/nasl/parser/foreach.rb +45 -0
  27. data/lib/nasl/parser/function.rb +45 -0
  28. data/lib/nasl/parser/global.rb +41 -0
  29. data/lib/nasl/parser/identifier.rb +43 -0
  30. data/lib/nasl/parser/if.rb +45 -0
  31. data/lib/nasl/parser/import.rb +41 -0
  32. data/lib/nasl/parser/include.rb +41 -0
  33. data/lib/nasl/parser/increment.rb +48 -0
  34. data/lib/nasl/parser/integer.rb +70 -0
  35. data/lib/nasl/parser/ip.rb +43 -0
  36. data/lib/nasl/parser/local.rb +41 -0
  37. data/lib/nasl/parser/lvalue.rb +43 -0
  38. data/lib/nasl/parser/node.rb +73 -0
  39. data/lib/nasl/parser/repeat.rb +43 -0
  40. data/lib/nasl/parser/repetition.rb +43 -0
  41. data/lib/nasl/parser/return.rb +41 -0
  42. data/lib/nasl/parser/string.rb +48 -0
  43. data/lib/nasl/parser/tree.rb +59 -0
  44. data/lib/nasl/parser/undefined.rb +35 -0
  45. data/lib/nasl/parser/while.rb +43 -0
  46. data/lib/nasl/parser.rb +45 -0
  47. data/lib/nasl/test.rb +98 -0
  48. data/lib/nasl/token.rb +69 -0
  49. data/lib/nasl/tokenizer.rb +327 -0
  50. data/lib/nasl/version.rb +3 -0
  51. data/lib/nasl.rb +52 -0
  52. data/nasl.gemspec +26 -0
  53. data/test/test_helper.rb +6 -0
  54. data/test/unit/parser/test_assignment.rb +111 -0
  55. data/test/unit/parser/test_blank.rb +44 -0
  56. data/test/unit/parser/test_block.rb +35 -0
  57. data/test/unit/parser/test_constant.rb +65 -0
  58. data/test/unit/parser/test_empty.rb +36 -0
  59. data/test/unit/parser/test_expressions.rb +57 -0
  60. data/test/unit/parser/test_function.rb +82 -0
  61. data/test/unit/parser/test_if.rb +85 -0
  62. data/test/unit/parser/test_include.rb +37 -0
  63. data/test/unit/parser/test_incr_decr.rb +51 -0
  64. data/test/unit/parser/test_ip.rb +33 -0
  65. data/test/unit/parser/test_return.rb +51 -0
  66. data/test/unit/parser/test_string.rb +46 -0
  67. data/test/unit/parser/test_whitespace.rb +56 -0
  68. data/test/unit/test_context.rb +240 -0
  69. data/test/unit/tokenizer/test_empty.rb +53 -0
  70. data/test/unit/tokenizer/test_integer.rb +68 -0
  71. data/test/unit/tokenizer/test_string.rb +94 -0
  72. metadata +161 -0
@@ -0,0 +1,513 @@
1
+ ################################################################################
2
+ # Copyright (c) 2011, Mak Kolybabi
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 BIT_AND
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 : export
74
+ { val[0] }
75
+ | function
76
+ { val[0] }
77
+ | statement
78
+ { val[0] }
79
+ ;
80
+
81
+ statement : simple
82
+ { val[0] }
83
+ | compound
84
+ { val[0] }
85
+ ;
86
+
87
+ ##############################################################################
88
+ # Root Statements
89
+ ##############################################################################
90
+
91
+ export : EXPORT function
92
+ { n(:Export, *val) }
93
+ ;
94
+
95
+ function : FUNCTION ident LPAREN params RPAREN block
96
+ { n(:Function, *val) }
97
+ | FUNCTION ident LPAREN RPAREN block
98
+ { n(:Function, *val) }
99
+ ;
100
+
101
+ simple : assign
102
+ { val[0] }
103
+ | break
104
+ { val[0] }
105
+ | call
106
+ { val[0] }
107
+ | continue
108
+ { val[0] }
109
+ | decr
110
+ { val[0] }
111
+ | empty
112
+ { val[0] }
113
+ | global
114
+ { val[0] }
115
+ | import
116
+ { val[0] }
117
+ | include
118
+ { val[0] }
119
+ | incr
120
+ { val[0] }
121
+ | local
122
+ { val[0] }
123
+ | rep
124
+ { val[0] }
125
+ | return
126
+ { val[0] }
127
+ ;
128
+
129
+ compound : block
130
+ { val[0] }
131
+ | for
132
+ { val[0] }
133
+ | foreach
134
+ { val[0] }
135
+ | if
136
+ { val[0] }
137
+ | repeat
138
+ { val[0] }
139
+ | while
140
+ { val[0] }
141
+ ;
142
+
143
+ ##############################################################################
144
+ # Simple Statements
145
+ ##############################################################################
146
+
147
+ assign : assign_exp SEMICOLON
148
+ { n(:Assignment, *val[0], val[1]) }
149
+ ;
150
+
151
+ break : BREAK SEMICOLON
152
+ { n(:Break, *val) }
153
+ ;
154
+
155
+ call : call_exp SEMICOLON
156
+ { n(:Call, *val[0], val[1]) }
157
+ ;
158
+
159
+ continue : CONTINUE SEMICOLON
160
+ { n(:Continue, *val) }
161
+ ;
162
+
163
+ decr : decr_exp SEMICOLON
164
+ { n(:Decrement, *val[0], val[1]) }
165
+ ;
166
+
167
+ empty : SEMICOLON
168
+ { n(:Empty, *val) }
169
+ ;
170
+
171
+ global : GLOBAL idents SEMICOLON
172
+ { n(:Global, *val) }
173
+ ;
174
+
175
+ incr : incr_exp SEMICOLON
176
+ { n(:Increment, *val[0], val[1]) }
177
+ ;
178
+
179
+ import : IMPORT LPAREN string RPAREN SEMICOLON
180
+ { n(:Import, *val) }
181
+ ;
182
+
183
+ include : INCLUDE LPAREN string RPAREN SEMICOLON
184
+ { n(:Include, *val) }
185
+ ;
186
+
187
+ local : LOCAL idents SEMICOLON
188
+ { n(:Local, *val) }
189
+ ;
190
+
191
+ rep : call_exp REP expr SEMICOLON
192
+ { n(:Repetition, n(:Call, *val[0]), *val[1..-1]) }
193
+ ;
194
+
195
+ return : RETURN expr SEMICOLON
196
+ { n(:Return, *val) }
197
+ | RETURN SEMICOLON
198
+ { n(:Return, *val) }
199
+ ;
200
+
201
+ ##############################################################################
202
+ # Compound Statements
203
+ ##############################################################################
204
+
205
+ block : LBRACE statements RBRACE
206
+ { n(:Block, *val) }
207
+ | LBRACE RBRACE
208
+ { n(:Block, *val) }
209
+ ;
210
+
211
+ for : FOR LPAREN field SEMICOLON expr SEMICOLON field RPAREN statement
212
+ { n(:For, *val) }
213
+ ;
214
+
215
+ foreach : FOREACH ident LPAREN expr RPAREN statement
216
+ { n(:Foreach, *val) }
217
+ ;
218
+
219
+ if : IF LPAREN expr RPAREN statement
220
+ { n(:If, *val) }
221
+ | IF LPAREN expr RPAREN statement ELSE statement
222
+ { n(:If, *val) }
223
+ ;
224
+
225
+ repeat : REPEAT statement UNTIL expr SEMICOLON
226
+ { n(:Repeat, *val) }
227
+ ;
228
+
229
+ while : WHILE LPAREN expr RPAREN statement
230
+ { n(:While, *val) }
231
+ ;
232
+
233
+ ##############################################################################
234
+ # Expressions
235
+ ##############################################################################
236
+
237
+ assign_exp : lval ASS_EQ expr
238
+ { val }
239
+ | lval ADD_EQ expr
240
+ { val }
241
+ | lval SUB_EQ expr
242
+ { val }
243
+ | lval MUL_EQ expr
244
+ { val }
245
+ | lval DIV_EQ expr
246
+ { val }
247
+ | lval MOD_EQ expr
248
+ { val }
249
+ | lval SRL_EQ expr
250
+ { val }
251
+ | lval SRA_EQ expr
252
+ { val }
253
+ | lval SLL_EQ expr
254
+ { val }
255
+ ;
256
+
257
+ call_exp : ident LPAREN args RPAREN
258
+ { val }
259
+ | ident LPAREN RPAREN
260
+ { val }
261
+
262
+ decr_exp : DECR lval
263
+ { val }
264
+ | lval DECR
265
+ { val }
266
+ ;
267
+
268
+ incr_exp : INCR lval
269
+ { val }
270
+ | lval INCR
271
+ { val }
272
+ ;
273
+
274
+ expr : LPAREN expr RPAREN
275
+ { n(:Expression, *val) }
276
+ | expr AND expr
277
+ { n(:Expression, *val) }
278
+ | NOT expr
279
+ { n(:Expression, *val) }
280
+ | expr OR expr
281
+ { n(:Expression, *val) }
282
+ | expr ADD expr
283
+ { n(:Expression, *val) }
284
+ | expr SUB expr
285
+ { n(:Expression, *val) }
286
+ | SUB expr =UMINUS
287
+ { n(:Expression, *val) }
288
+ | BIT_NOT expr
289
+ { n(:Expression, *val) }
290
+ | expr MUL expr
291
+ { n(:Expression, *val) }
292
+ | expr EXP expr
293
+ { n(:Expression, *val) }
294
+ | expr DIV expr
295
+ { n(:Expression, *val) }
296
+ | expr MOD expr
297
+ { n(:Expression, *val) }
298
+ | expr BIT_AND expr
299
+ { n(:Expression, *val) }
300
+ | expr BIT_XOR expr
301
+ { n(:Expression, *val) }
302
+ | expr BIT_OR expr
303
+ { n(:Expression, *val) }
304
+ | expr BIT_SRA expr
305
+ { n(:Expression, *val) }
306
+ | expr BIT_SRL expr
307
+ { n(:Expression, *val) }
308
+ | expr BIT_SLL expr
309
+ { n(:Expression, *val) }
310
+ | incr_exp
311
+ { n(:Increment, *val[0]) }
312
+ | decr_exp
313
+ { n(:Decrement, *val[0]) }
314
+ | expr SUBSTR_EQ expr
315
+ { n(:Expression, *val) }
316
+ | expr SUBSTR_NE expr
317
+ { n(:Expression, *val) }
318
+ | expr REGEX_EQ expr
319
+ { n(:Expression, *val) }
320
+ | expr REGEX_NE expr
321
+ { n(:Expression, *val) }
322
+ | expr CMP_LT expr
323
+ { n(:Expression, *val) }
324
+ | expr CMP_GT expr
325
+ { n(:Expression, *val) }
326
+ | expr CMP_EQ expr
327
+ { n(:Expression, *val) }
328
+ | expr CMP_NE expr
329
+ { n(:Expression, *val) }
330
+ | expr CMP_GE expr
331
+ { n(:Expression, *val) }
332
+ | expr CMP_LE expr
333
+ { n(:Expression, *val) }
334
+ | assign_exp
335
+ { n(:Assignment, *val[0]) }
336
+ | string
337
+ { val[0] }
338
+ | call_exp
339
+ { n(:Call, *val[0]) }
340
+ | lval
341
+ { val[0] }
342
+ | ip
343
+ { val[0] }
344
+ | int
345
+ { val[0] }
346
+ | undef
347
+ { val[0] }
348
+ ;
349
+
350
+ ##############################################################################
351
+ # Named Components
352
+ ##############################################################################
353
+
354
+ arg : ident COLON expr
355
+ { n(:Argument, *val) }
356
+ | expr
357
+ { n(:Argument, *val) }
358
+ ;
359
+
360
+ lval : ident indexes
361
+ { n(:Lvalue, *val) }
362
+ | ident
363
+ { n(:Lvalue, *val) }
364
+ ;
365
+
366
+ ##############################################################################
367
+ # Anonymous Components
368
+ ##############################################################################
369
+
370
+ args : arg COMMA args
371
+ { [val[0]] + val[2] }
372
+ | arg
373
+ { [val[0]] }
374
+ ;
375
+
376
+ field : assign_exp
377
+ { val[0] }
378
+ | call_exp
379
+ { val[0] }
380
+ | decr_exp
381
+ { val[0] }
382
+ | incr_exp
383
+ { val[0] }
384
+ | /* Blank */
385
+ { nil }
386
+ ;
387
+
388
+ idents : ident COMMA idents
389
+ { [val[0]] + val[2] }
390
+ | ident
391
+ { [val[0]] }
392
+ ;
393
+
394
+ indexes : LBRACK expr RBRACK indexes
395
+ { [val[1]] + val[3] }
396
+ | LBRACK expr RBRACK
397
+ { [val[1]] }
398
+ ;
399
+
400
+ params : ident COMMA params
401
+ { [val[0]] + val[2] }
402
+ | ident
403
+ { [val[0]] }
404
+ ;
405
+
406
+ statements : statement statements
407
+ { [val[0]] + val[1] }
408
+ | statement
409
+ { [val[0]] }
410
+ ;
411
+
412
+ ##############################################################################
413
+ # Literals
414
+ ##############################################################################
415
+
416
+ ident : IDENT
417
+ { n(:Identifier, *val) }
418
+ | REP
419
+ { n(:Identifier, *val) }
420
+ ;
421
+
422
+ int : INT_DEC
423
+ { n(:Integer, *val) }
424
+ | INT_HEX
425
+ { n(:Integer, *val) }
426
+ | INT_OCT
427
+ { n(:Integer, *val) }
428
+ | FALSE
429
+ { n(:Integer, *val) }
430
+ | TRUE
431
+ { n(:Integer, *val) }
432
+ ;
433
+
434
+ ip : int PERIOD int PERIOD int PERIOD int
435
+ { n(:Ip, *val) }
436
+
437
+ string : DATA
438
+ { n(:String, *val) }
439
+ | STRING
440
+ { n(:String, *val) }
441
+ ;
442
+
443
+ undef : UNDEF
444
+ { n(:Undefined, *val) }
445
+ ;
446
+ end
447
+
448
+ ---- header ----
449
+
450
+ require 'nasl/parser/tree'
451
+
452
+ require 'nasl/parser/argument'
453
+ require 'nasl/parser/assigment'
454
+ require 'nasl/parser/block'
455
+ require 'nasl/parser/break'
456
+ require 'nasl/parser/call'
457
+ require 'nasl/parser/continue'
458
+ require 'nasl/parser/decrement'
459
+ require 'nasl/parser/empty'
460
+ require 'nasl/parser/export'
461
+ require 'nasl/parser/expression'
462
+ require 'nasl/parser/for'
463
+ require 'nasl/parser/foreach'
464
+ require 'nasl/parser/function'
465
+ require 'nasl/parser/global'
466
+ require 'nasl/parser/identifier'
467
+ require 'nasl/parser/if'
468
+ require 'nasl/parser/import'
469
+ require 'nasl/parser/include'
470
+ require 'nasl/parser/increment'
471
+ require 'nasl/parser/integer'
472
+ require 'nasl/parser/ip'
473
+ require 'nasl/parser/local'
474
+ require 'nasl/parser/lvalue'
475
+ require 'nasl/parser/repeat'
476
+ require 'nasl/parser/repetition'
477
+ require 'nasl/parser/return'
478
+ require 'nasl/parser/string'
479
+ require 'nasl/parser/undefined'
480
+ require 'nasl/parser/while'
481
+
482
+ ---- inner ----
483
+
484
+ def n(cls, *args)
485
+ begin
486
+ Nasl.const_get(cls).new(@tree, *args)
487
+ rescue
488
+ puts "An exception occurred during the creation of a #{cls} instance."
489
+ puts
490
+ puts "The arguments passed to the constructer were:"
491
+ puts args
492
+ puts
493
+ puts @tok.last.context
494
+ puts
495
+ raise
496
+ end
497
+ end
498
+
499
+ def on_error(type, value, stack)
500
+ raise ParseException, "The language's grammar does not permit #{value.name} to appear here", value.context
501
+ end
502
+
503
+ def next_token
504
+ @tok = @tkz.get_token
505
+ end
506
+
507
+ def parse(env, code, path)
508
+ @tree = Tree.new(env)
509
+ @tkz = Tokenizer.new(code, path)
510
+ @tree.concat(do_parse)
511
+ end
512
+
513
+ ---- footer ----