racc 1.4.13 → 1.5.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 (101) hide show
  1. checksums.yaml +5 -5
  2. data/COPYING +22 -515
  3. data/README.ja.rdoc +3 -4
  4. data/README.rdoc +6 -8
  5. data/Rakefile +30 -53
  6. data/bin/racc +39 -27
  7. data/ext/racc/com/headius/racc/Cparse.java +66 -23
  8. data/ext/racc/{cparse.c → cparse/cparse.c} +78 -47
  9. data/ext/racc/{extconf.rb → cparse/extconf.rb} +2 -1
  10. data/lib/racc/compat.rb +5 -4
  11. data/lib/racc/debugflags.rb +5 -4
  12. data/lib/racc/exception.rb +5 -4
  13. data/lib/racc/grammar.rb +25 -22
  14. data/lib/racc/grammarfileparser.rb +10 -8
  15. data/lib/racc/info.rb +6 -5
  16. data/lib/racc/iset.rb +6 -5
  17. data/lib/racc/logfilegenerator.rb +6 -5
  18. data/lib/racc/parser-text.rb +23 -24
  19. data/lib/racc/parser.rb +23 -24
  20. data/lib/racc/parserfilegenerator.rb +10 -10
  21. data/lib/racc/sourcetext.rb +5 -4
  22. data/lib/racc/state.rb +13 -12
  23. data/lib/racc/statetransitiontable.rb +7 -6
  24. data/rdoc/ja/command.ja.html +1 -1
  25. data/sample/array.y +1 -1
  26. data/sample/array2.y +1 -1
  27. data/sample/calc-ja.y +2 -2
  28. data/sample/calc.y +2 -2
  29. data/sample/conflict.y +1 -1
  30. data/sample/hash.y +1 -1
  31. data/sample/lalr.y +1 -1
  32. data/sample/lists.y +1 -1
  33. data/sample/syntax.y +1 -1
  34. data/sample/yyerr.y +1 -1
  35. data/test/assets/cadenza.y +170 -0
  36. data/test/assets/cast.y +926 -0
  37. data/test/assets/csspool.y +729 -0
  38. data/test/assets/edtf.y +583 -0
  39. data/test/assets/error_recovery.y +35 -0
  40. data/test/assets/huia.y +318 -0
  41. data/test/assets/intp.y +4 -4
  42. data/test/assets/journey.y +47 -0
  43. data/test/assets/liquor.y +313 -0
  44. data/test/assets/machete.y +423 -0
  45. data/test/assets/macruby.y +2197 -0
  46. data/test/assets/mailp.y +27 -27
  47. data/test/assets/mediacloth.y +599 -0
  48. data/test/assets/mof.y +649 -0
  49. data/test/assets/namae.y +302 -0
  50. data/test/assets/nasl.y +626 -0
  51. data/test/assets/nokogiri-css.y +255 -0
  52. data/test/assets/nullbug2.y +2 -2
  53. data/test/assets/opal.y +1807 -0
  54. data/test/assets/php_serialization.y +98 -0
  55. data/test/assets/recv.y +20 -20
  56. data/test/assets/riml.y +665 -0
  57. data/test/assets/ruby18.y +1943 -0
  58. data/test/assets/ruby19.y +2174 -0
  59. data/test/assets/ruby20.y +2350 -0
  60. data/test/assets/ruby21.y +2359 -0
  61. data/test/assets/ruby22.y +2381 -0
  62. data/test/assets/syntax.y +1 -1
  63. data/test/assets/tp_plus.y +622 -0
  64. data/test/assets/twowaysql.y +278 -0
  65. data/test/helper.rb +69 -41
  66. data/test/regress/cadenza +796 -0
  67. data/test/regress/cast +3428 -0
  68. data/test/regress/csspool +2314 -0
  69. data/test/regress/edtf +1794 -0
  70. data/test/regress/huia +1392 -0
  71. data/test/regress/journey +222 -0
  72. data/test/regress/liquor +885 -0
  73. data/test/regress/machete +833 -0
  74. data/test/regress/mediacloth +1463 -0
  75. data/test/regress/mof +1368 -0
  76. data/test/regress/namae +634 -0
  77. data/test/regress/nasl +2058 -0
  78. data/test/regress/nokogiri-css +836 -0
  79. data/test/regress/opal +6431 -0
  80. data/test/regress/php_serialization +336 -0
  81. data/test/regress/riml +3283 -0
  82. data/test/regress/ruby18 +6344 -0
  83. data/test/regress/ruby22 +7460 -0
  84. data/test/regress/tp_plus +1933 -0
  85. data/test/regress/twowaysql +556 -0
  86. data/test/test_chk_y.rb +1 -0
  87. data/test/test_racc_command.rb +186 -2
  88. data/test/test_scan_y.rb +1 -0
  89. data/test/testscanner.rb +1 -1
  90. metadata +60 -83
  91. data/DEPENDS +0 -4
  92. data/Manifest.txt +0 -101
  93. data/bin/racc2y +0 -195
  94. data/bin/y2racc +0 -339
  95. data/ext/racc/depend +0 -1
  96. data/fastcache/extconf.rb +0 -2
  97. data/fastcache/fastcache.c +0 -185
  98. data/misc/dist.sh +0 -31
  99. data/setup.rb +0 -1587
  100. data/tasks/doc.rb +0 -12
  101. data/tasks/email.rb +0 -55
@@ -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 constructor 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 ----