yap-shell-parser 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d22f0856a5b1b260c5d9ade076db5d0ec84ed0d3
4
- data.tar.gz: d7281d94d9473c1eee9c98de6e309395cfa21352
3
+ metadata.gz: f1721a734dd55506e55a1d3c5c6749a7d4177b0a
4
+ data.tar.gz: 2211073698e05b3cd2d8cb994a396d431dba1880
5
5
  SHA512:
6
- metadata.gz: 99bd043d5beb4791c874c695cd73f2178826e3b976729412e8658116d3b45554f6dfea34230ac45c027f08d396320c78f808f57c51ae05de47242354ed71f37a
7
- data.tar.gz: 277240948738b082d8da1bc74253be78c4a6128f4f894024e3cc03be538600fef50f9baa4887fddd6ecbb8e40970b7e99da221fa9f19ffa5139f3c8f671620d1
6
+ metadata.gz: 5ab7eee677398b1f24a546f1512aad1fd9b0f4e10d6dfffbca5471b8e477d5bbd33372365f51a74652251dfec6707ea526b388715de0ea10a40b171183b73259
7
+ data.tar.gz: a5ed3d26e255794023a8265e807360469b75cb245fac33ac953f72babda1681a87756c353849b31b9a2b171b9d68bdc144d6cc887d8cd26c27c15999e019a004
@@ -1,3 +1,3 @@
1
1
  #!/bin/bash
2
2
 
3
- racc -t lib/yap/shell/parser/grammar.y -o lib/yap/shell/parser.rb
3
+ racc -t lib/yap/shell/parser/grammar.y -o lib/yap/shell/parser_impl.rb
data/bin/compile_parser CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/bin/bash
2
2
 
3
- racc lib/yap/shell/parser/grammar.y -o lib/yap/shell/parser.rb
3
+ racc lib/yap/shell/parser/grammar.y -o lib/yap/shell/parser_impl.rb
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # convert Array-like string into Ruby's Array.
4
4
 
5
- class Yap::Shell::Parser
5
+ class Yap::Shell::ParserImpl
6
6
  token Command LiteralCommand Argument Heredoc InternalEval Separator Conditional Pipe Redirection LValue RValue
7
7
  #
8
8
  # prechigh
@@ -77,12 +77,8 @@ internal_eval : InternalEval
77
77
 
78
78
 
79
79
  ---- inner
80
- $LOAD_PATH.unshift File.dirname(__FILE__) + "/../../"
81
- require 'yap/shell/parser/lexer'
82
- require 'yap/shell/parser/nodes'
83
-
84
80
  include Yap::Shell::Parser::Nodes
85
-
81
+ #=end
86
82
  def parse(str)
87
83
  # @yydebug = true
88
84
 
@@ -101,7 +97,7 @@ internal_eval : InternalEval
101
97
  ---- footer
102
98
 
103
99
  if $0 == __FILE__
104
- $LOAD_PATH.unshift File.dirname(__FILE__) + "/../../"
100
+ $LOAD_PATH.unshift File.dirname(__FILE__) + "/lib/"
105
101
  require 'yap/shell/parser/lexer'
106
102
  require 'yap/shell/parser/nodes'
107
103
  [
@@ -33,11 +33,11 @@ module Yap::Shell
33
33
  end
34
34
  end
35
35
 
36
- ARG = /[^\s;\|\(\)\{\}\[\]\&\!\\\<][^\s;\|\(\)\{\}\[\]\&\!\>\<]*/
36
+ COMMAND_SUBSTITUTION = /\A(`|\$\()/
37
+ ARG = /[^\s;\|\(\)\{\}\[\]\&\!\\\<`][^\s;\|\(\)\{\}\[\]\&\!\>\<`]*/
37
38
  COMMAND = /\A(#{ARG})/
38
39
  LITERAL_COMMAND = /\A\\(#{ARG})/
39
40
  WHITESPACE = /\A[^\n\S]+/
40
- ARGUMENT = /\A(#{ARG}+)/
41
41
  LH_ASSIGNMENT = /\A(([A-z_][\w]*)=)/
42
42
  RH_VALUE = /\A(\S+)/
43
43
  STATEMENT_TERMINATOR = /\A(;)/
@@ -61,7 +61,9 @@ module Yap::Shell
61
61
  process_next_chunk = -> { @chunk = str.slice(@current_position..-1) ; @chunk != "" }
62
62
 
63
63
  while process_next_chunk.call
64
- result = subgroup_token ||
64
+ result =
65
+ command_substitution_token ||
66
+ subgroup_token ||
65
67
  assignment_token ||
66
68
  literal_command_token ||
67
69
  command_token ||
@@ -161,7 +163,7 @@ module Yap::Shell
161
163
  end
162
164
 
163
165
  def argument_token
164
- if @looking_for_args && md=@chunk.match(ARGUMENT)
166
+ if @looking_for_args
165
167
  str = ''
166
168
  i = 0
167
169
  loop do
@@ -170,8 +172,7 @@ module Yap::Shell
170
172
  result = process_string @chunk[i..-1], ch
171
173
  str << result.str
172
174
  i += result.consumed_length
173
-
174
- elsif ch !~ ARGUMENT
175
+ elsif ch =~ /[\s\|;&]/
175
176
  break
176
177
  else
177
178
  str << ch
@@ -230,6 +231,18 @@ module Yap::Shell
230
231
  end
231
232
  end
232
233
 
234
+ def command_substitution_token
235
+ if md=@chunk.match(COMMAND_SUBSTITUTION)
236
+ delimiter = md[1] == "$(" ? ")" : md[1]
237
+ result = process_string @chunk[md[0].length-1..-1], delimiter
238
+ token :BeginSubcommand, md[1]
239
+ @tokens.push *self.class.new.tokenize(result.str)
240
+ token :EndSubcommand, delimiter
241
+
242
+ result.consumed_length + (md[0].length - 1)
243
+ end
244
+ end
245
+
233
246
  def process_internal_eval(input_str, consumed:0)
234
247
  scope = []
235
248
  words = []
@@ -1,5 +1,9 @@
1
1
  require 'yap/shell/parser'
2
2
 
3
- class Yap::Shell::Parser
4
- VERSION = "0.0.1"
3
+ module Yap
4
+ module Shell
5
+ module Parser
6
+ VERSION = "0.0.3"
7
+ end
8
+ end
5
9
  end
@@ -1,381 +1,14 @@
1
- #
2
- # DO NOT MODIFY!!!!
3
- # This file is automatically generated by Racc 1.4.9
4
- # from Racc grammer file "".
5
- #
6
-
7
- require 'racc/parser.rb'
8
1
  module Yap
9
2
  module Shell
10
- class Parser < Racc::Parser
11
-
12
- module_eval(<<'...end grammar.y/module_eval...', 'grammar.y', 80)
13
- $LOAD_PATH.unshift File.dirname(__FILE__) + "/../../"
14
- require 'yap/shell/parser/lexer'
15
- require 'yap/shell/parser/nodes'
16
-
17
- include Yap::Shell::Parser::Nodes
18
-
19
- def parse(str)
20
- # @yydebug = true
21
-
22
- @q = Yap::Shell::Parser::Lexer.new.tokenize(str)
23
- # @q.push [false, '$'] # is optional from Racc 1.3.7
24
- # puts @q.inspect
25
- # puts "---- parse tree follows ----"
26
- __send__(Racc_Main_Parsing_Routine, _racc_setup(), false)
27
- #do_parse
28
- end
29
-
30
- def next_token
31
- @q.shift
32
- end
33
-
34
- ...end grammar.y/module_eval...
35
- ##### State transition tables begin ###
36
-
37
- racc_action_table = [
38
- 15, 16, 29, 23, 17, 29, 15, 16, 24, 13,
39
- 17, 6, 15, 16, 27, 13, 17, 6, 15, 16,
40
- 31, 13, 17, 6, 15, 16, 21, 13, 17, 6,
41
- 15, 16, 20, 13, 19, 6, 19, 18, 36, 26,
42
- 37, 35, 37, 20, 21 ]
43
-
44
- racc_action_check = [
45
- 0, 0, 16, 9, 0, 15, 6, 6, 9, 0,
46
- 6, 0, 21, 21, 13, 6, 21, 6, 20, 20,
47
- 18, 21, 20, 21, 19, 19, 4, 20, 19, 20,
48
- 12, 12, 3, 19, 22, 19, 2, 1, 26, 12,
49
- 28, 22, 30, 32, 33 ]
50
-
51
- racc_action_pointer = [
52
- -2, 37, 29, 24, 17, nil, 4, nil, nil, -2,
53
- nil, nil, 28, 2, nil, 1, -2, nil, 20, 22,
54
- 16, 10, 27, nil, nil, nil, 26, nil, 36, nil,
55
- 38, nil, 35, 35, nil, nil, nil, nil ]
56
-
57
- racc_action_default = [
58
- -28, -28, -1, -3, -5, -7, -28, -9, -10, -12,
59
- -14, -15, -16, -28, -20, -21, -23, -27, -28, -28,
60
- -28, -28, -28, -11, -13, -17, -28, -19, -22, -25,
61
- -24, 38, -2, -4, -6, -8, -18, -26 ]
62
-
63
- racc_goto_table = [
64
- 2, 28, 30, 33, 32, 34, 22, 25, 1 ]
65
-
66
- racc_goto_check = [
67
- 2, 13, 13, 4, 3, 5, 2, 10, 1 ]
68
-
69
- racc_goto_pointer = [
70
- nil, 8, 0, -15, -17, -16, nil, nil, nil, nil,
71
- -5, nil, nil, -14 ]
72
-
73
- racc_goto_default = [
74
- nil, nil, nil, 3, 4, 5, 7, 8, 9, 10,
75
- 11, 12, 14, nil ]
76
-
77
- racc_reduce_table = [
78
- 0, 0, :racc_error,
79
- 1, 16, :_reduce_none,
80
- 3, 17, :_reduce_2,
81
- 1, 17, :_reduce_3,
82
- 3, 18, :_reduce_4,
83
- 1, 18, :_reduce_none,
84
- 3, 19, :_reduce_6,
85
- 1, 19, :_reduce_none,
86
- 3, 20, :_reduce_8,
87
- 1, 20, :_reduce_none,
88
- 1, 20, :_reduce_none,
89
- 2, 21, :_reduce_11,
90
- 1, 21, :_reduce_none,
91
- 2, 23, :_reduce_13,
92
- 1, 23, :_reduce_none,
93
- 1, 23, :_reduce_none,
94
- 1, 23, :_reduce_none,
95
- 2, 24, :_reduce_17,
96
- 3, 26, :_reduce_18,
97
- 2, 26, :_reduce_19,
98
- 1, 25, :_reduce_none,
99
- 1, 27, :_reduce_21,
100
- 2, 27, :_reduce_22,
101
- 1, 27, :_reduce_23,
102
- 2, 27, :_reduce_24,
103
- 1, 28, :_reduce_25,
104
- 2, 28, :_reduce_26,
105
- 1, 22, :_reduce_27 ]
106
-
107
- racc_reduce_n = 28
108
-
109
- racc_shift_n = 38
110
-
111
- racc_token_table = {
112
- false => 0,
113
- :error => 1,
114
- :Command => 2,
115
- :LiteralCommand => 3,
116
- :Argument => 4,
117
- :Heredoc => 5,
118
- :InternalEval => 6,
119
- :Separator => 7,
120
- :Conditional => 8,
121
- :Pipe => 9,
122
- :Redirection => 10,
123
- :LValue => 11,
124
- :RValue => 12,
125
- "(" => 13,
126
- ")" => 14 }
127
-
128
- racc_nt_base = 15
129
-
130
- racc_use_result_var = true
131
-
132
- Racc_arg = [
133
- racc_action_table,
134
- racc_action_check,
135
- racc_action_default,
136
- racc_action_pointer,
137
- racc_goto_table,
138
- racc_goto_check,
139
- racc_goto_default,
140
- racc_goto_pointer,
141
- racc_nt_base,
142
- racc_reduce_table,
143
- racc_token_table,
144
- racc_shift_n,
145
- racc_reduce_n,
146
- racc_use_result_var ]
147
-
148
- Racc_token_to_s_table = [
149
- "$end",
150
- "error",
151
- "Command",
152
- "LiteralCommand",
153
- "Argument",
154
- "Heredoc",
155
- "InternalEval",
156
- "Separator",
157
- "Conditional",
158
- "Pipe",
159
- "Redirection",
160
- "LValue",
161
- "RValue",
162
- "\"(\"",
163
- "\")\"",
164
- "$start",
165
- "program",
166
- "stmts",
167
- "stmt",
168
- "pipeline",
169
- "stmts2",
170
- "command_w_heredoc",
171
- "internal_eval",
172
- "command_w_redirects",
173
- "command_w_vars",
174
- "command",
175
- "vars",
176
- "command2",
177
- "args" ]
178
-
179
- Racc_debug_parser = false
180
-
181
- ##### State transition tables end #####
182
-
183
- # reduce 0 omitted
184
-
185
- # reduce 1 omitted
186
-
187
- module_eval(<<'.,.,', 'grammar.y', 23)
188
- def _reduce_2(val, _values, result)
189
- result = StatementsNode.new(val[0], val[2])
190
- result
191
- end
192
- .,.,
193
-
194
- module_eval(<<'.,.,', 'grammar.y', 25)
195
- def _reduce_3(val, _values, result)
196
- result = StatementsNode.new(val[0])
197
- result
198
- end
199
- .,.,
200
-
201
- module_eval(<<'.,.,', 'grammar.y', 28)
202
- def _reduce_4(val, _values, result)
203
- result = ConditionalNode.new(val[1].value, val[0], val[2])
204
- result
205
- end
206
- .,.,
207
-
208
- # reduce 5 omitted
209
-
210
- module_eval(<<'.,.,', 'grammar.y', 32)
211
- def _reduce_6(val, _values, result)
212
- result = PipelineNode.new(val[0], val[2])
213
- result
214
- end
215
- .,.,
216
-
217
- # reduce 7 omitted
218
-
219
- module_eval(<<'.,.,', 'grammar.y', 36)
220
- def _reduce_8(val, _values, result)
221
- result = val[1]
222
- result
223
- end
224
- .,.,
225
-
226
- # reduce 9 omitted
227
-
228
- # reduce 10 omitted
229
-
230
- module_eval(<<'.,.,', 'grammar.y', 41)
231
- def _reduce_11(val, _values, result)
232
- val[0].heredoc = val[1] ; result = val[0]
233
- result
234
- end
235
- .,.,
236
-
237
- # reduce 12 omitted
238
-
239
- module_eval(<<'.,.,', 'grammar.y', 45)
240
- def _reduce_13(val, _values, result)
241
- val[0].redirects << RedirectionNode.new(val[1].value, val[1].attrs[:target]) ; result = val[0]
242
- result
243
- end
244
- .,.,
245
-
246
- # reduce 14 omitted
247
-
248
- # reduce 15 omitted
249
-
250
- # reduce 16 omitted
251
-
252
- module_eval(<<'.,.,', 'grammar.y', 51)
253
- def _reduce_17(val, _values, result)
254
- result = EnvWrapperNode.new(val[0], val[1])
255
- result
256
- end
257
- .,.,
258
-
259
- module_eval(<<'.,.,', 'grammar.y', 54)
260
- def _reduce_18(val, _values, result)
261
- val[0].add_var(val[1].value, val[2].value) ; result = val[0]
262
- result
263
- end
264
- .,.,
265
-
266
- module_eval(<<'.,.,', 'grammar.y', 56)
267
- def _reduce_19(val, _values, result)
268
- result = EnvNode.new(val[0].value, val[1].value)
269
- result
270
- end
271
- .,.,
272
-
273
- # reduce 20 omitted
274
-
275
- module_eval(<<'.,.,', 'grammar.y', 61)
276
- def _reduce_21(val, _values, result)
277
- result = CommandNode.new(val[0].value)
278
- result
279
- end
280
- .,.,
281
-
282
- module_eval(<<'.,.,', 'grammar.y', 63)
283
- def _reduce_22(val, _values, result)
284
- result = CommandNode.new(val[0].value, val[1].flatten)
285
- result
286
- end
287
- .,.,
288
-
289
- module_eval(<<'.,.,', 'grammar.y', 65)
290
- def _reduce_23(val, _values, result)
291
- result = CommandNode.new(val[0].value, literal:true)
292
- result
293
- end
294
- .,.,
295
-
296
- module_eval(<<'.,.,', 'grammar.y', 67)
297
- def _reduce_24(val, _values, result)
298
- result = CommandNode.new(val[0].value, val[1].flatten, literal:true)
299
- result
300
- end
301
- .,.,
302
-
303
- module_eval(<<'.,.,', 'grammar.y', 70)
304
- def _reduce_25(val, _values, result)
305
- result = [val[0].value]
306
- result
307
- end
308
- .,.,
309
-
310
- module_eval(<<'.,.,', 'grammar.y', 72)
311
- def _reduce_26(val, _values, result)
312
- result = [val[0], val[1].value]
313
- result
314
- end
315
- .,.,
316
-
317
- module_eval(<<'.,.,', 'grammar.y', 75)
318
- def _reduce_27(val, _values, result)
319
- result = InternalEvalNode.new(val[0].value)
320
- result
3
+ module Parser
4
+ def self.new
5
+ Yap::Shell::ParserImpl.new
6
+ end
7
+ end
321
8
  end
322
- .,.,
323
-
324
- def _reduce_none(val, _values, result)
325
- val[0]
326
9
  end
327
10
 
328
- end # class Parser
329
- end # module Shell
330
- end # module Yap
331
-
332
-
333
- if $0 == __FILE__
334
- $LOAD_PATH.unshift File.dirname(__FILE__) + "/../../"
335
- require 'yap/shell/parser/lexer'
336
- require 'yap/shell/parser/nodes'
337
- [
338
- # "echo foo",
339
- # "echo foo ; echo bar baz yep",
340
- # "echo foo && echo bar baz yep",
341
- # "echo foo && echo bar && ls foo && ls bar",
342
- # "echo foo ; echo bar baz yep ; ls foo",
343
- # "echo foo && echo bar ; ls baz",
344
- # "echo foo && echo bar ; ls baz ; echo zach || echo gretchen",
345
- # "echo foo | bar",
346
- # "echo foo | bar && foo | bar",
347
- # "foo && bar ; word || baz ; yep | grep -v foo",
348
- # "( foo )",
349
- # "( foo a b && bar c d )",
350
- # "( foo a b && (bar c d | baz e f))",
351
- # "((((foo))))",
352
- # "foo -b -c ; (this ;that ;the; other ;thing) && yep",
353
- # "foo -b -c ; (this ;that && other ;thing) && yep",
354
- # "4 + 5",
355
- # "!'hello' ; 4 - 4 && 10 + 3",
356
- # "\\foo <<-EOT\nbar\nEOT",
357
- # "ls | grep md | grep WISH",
358
- # "(!upcase)",
359
- # "echo foo > bar.txt",
360
- # "ls -l > a.txt ; echo f 2> b.txt ; cat b &> c.txt ; du -sh 1>&2 1>hey.txt",
361
- # "!Dir.chdir('..')",
362
- # "FOO=123",
363
- # "FOO=123 BAR=345",
364
- # "FOO=abc bar=2314 car=14ab ls -l",
365
- "FOO=abc BAR='hello world' ls -l ; CAR=f echo foo && say hi"
366
- ].each do |src|
367
- puts 'parsing:'
368
- print src
369
- puts
370
- puts 'result:'
371
- require 'pp'
372
- ast = Yap::Shell::Parser.new.parse(src)
373
- pp ast
374
- end
375
-
376
-
377
- # puts "---- Evaluating"
378
- # require 'pry'
379
- # binding.pry
380
- # Evaluator.new.evaltree(ast)
381
- end
11
+ $LOAD_PATH.unshift File.dirname(__FILE__) + "/../../"
12
+ require 'yap/shell/parser/lexer'
13
+ require 'yap/shell/parser/nodes'
14
+ require 'yap/shell/parser_impl'
@@ -0,0 +1,377 @@
1
+ #
2
+ # DO NOT MODIFY!!!!
3
+ # This file is automatically generated by Racc 1.4.9
4
+ # from Racc grammer file "".
5
+ #
6
+
7
+ require 'racc/parser.rb'
8
+ module Yap
9
+ module Shell
10
+ class ParserImpl < Racc::Parser
11
+
12
+ module_eval(<<'...end grammar.y/module_eval...', 'grammar.y', 80)
13
+ include Yap::Shell::Parser::Nodes
14
+ #=end
15
+ def parse(str)
16
+ # @yydebug = true
17
+
18
+ @q = Yap::Shell::Parser::Lexer.new.tokenize(str)
19
+ # @q.push [false, '$'] # is optional from Racc 1.3.7
20
+ # puts @q.inspect
21
+ # puts "---- parse tree follows ----"
22
+ __send__(Racc_Main_Parsing_Routine, _racc_setup(), false)
23
+ #do_parse
24
+ end
25
+
26
+ def next_token
27
+ @q.shift
28
+ end
29
+
30
+ ...end grammar.y/module_eval...
31
+ ##### State transition tables begin ###
32
+
33
+ racc_action_table = [
34
+ 15, 16, 29, 23, 17, 29, 15, 16, 24, 13,
35
+ 17, 6, 15, 16, 27, 13, 17, 6, 15, 16,
36
+ 31, 13, 17, 6, 15, 16, 21, 13, 17, 6,
37
+ 15, 16, 20, 13, 19, 6, 19, 18, 36, 26,
38
+ 37, 35, 37, 20, 21 ]
39
+
40
+ racc_action_check = [
41
+ 0, 0, 16, 9, 0, 15, 6, 6, 9, 0,
42
+ 6, 0, 21, 21, 13, 6, 21, 6, 20, 20,
43
+ 18, 21, 20, 21, 19, 19, 4, 20, 19, 20,
44
+ 12, 12, 3, 19, 22, 19, 2, 1, 26, 12,
45
+ 28, 22, 30, 32, 33 ]
46
+
47
+ racc_action_pointer = [
48
+ -2, 37, 29, 24, 17, nil, 4, nil, nil, -2,
49
+ nil, nil, 28, 2, nil, 1, -2, nil, 20, 22,
50
+ 16, 10, 27, nil, nil, nil, 26, nil, 36, nil,
51
+ 38, nil, 35, 35, nil, nil, nil, nil ]
52
+
53
+ racc_action_default = [
54
+ -28, -28, -1, -3, -5, -7, -28, -9, -10, -12,
55
+ -14, -15, -16, -28, -20, -21, -23, -27, -28, -28,
56
+ -28, -28, -28, -11, -13, -17, -28, -19, -22, -25,
57
+ -24, 38, -2, -4, -6, -8, -18, -26 ]
58
+
59
+ racc_goto_table = [
60
+ 2, 28, 30, 33, 32, 34, 22, 25, 1 ]
61
+
62
+ racc_goto_check = [
63
+ 2, 13, 13, 4, 3, 5, 2, 10, 1 ]
64
+
65
+ racc_goto_pointer = [
66
+ nil, 8, 0, -15, -17, -16, nil, nil, nil, nil,
67
+ -5, nil, nil, -14 ]
68
+
69
+ racc_goto_default = [
70
+ nil, nil, nil, 3, 4, 5, 7, 8, 9, 10,
71
+ 11, 12, 14, nil ]
72
+
73
+ racc_reduce_table = [
74
+ 0, 0, :racc_error,
75
+ 1, 16, :_reduce_none,
76
+ 3, 17, :_reduce_2,
77
+ 1, 17, :_reduce_3,
78
+ 3, 18, :_reduce_4,
79
+ 1, 18, :_reduce_none,
80
+ 3, 19, :_reduce_6,
81
+ 1, 19, :_reduce_none,
82
+ 3, 20, :_reduce_8,
83
+ 1, 20, :_reduce_none,
84
+ 1, 20, :_reduce_none,
85
+ 2, 21, :_reduce_11,
86
+ 1, 21, :_reduce_none,
87
+ 2, 23, :_reduce_13,
88
+ 1, 23, :_reduce_none,
89
+ 1, 23, :_reduce_none,
90
+ 1, 23, :_reduce_none,
91
+ 2, 24, :_reduce_17,
92
+ 3, 26, :_reduce_18,
93
+ 2, 26, :_reduce_19,
94
+ 1, 25, :_reduce_none,
95
+ 1, 27, :_reduce_21,
96
+ 2, 27, :_reduce_22,
97
+ 1, 27, :_reduce_23,
98
+ 2, 27, :_reduce_24,
99
+ 1, 28, :_reduce_25,
100
+ 2, 28, :_reduce_26,
101
+ 1, 22, :_reduce_27 ]
102
+
103
+ racc_reduce_n = 28
104
+
105
+ racc_shift_n = 38
106
+
107
+ racc_token_table = {
108
+ false => 0,
109
+ :error => 1,
110
+ :Command => 2,
111
+ :LiteralCommand => 3,
112
+ :Argument => 4,
113
+ :Heredoc => 5,
114
+ :InternalEval => 6,
115
+ :Separator => 7,
116
+ :Conditional => 8,
117
+ :Pipe => 9,
118
+ :Redirection => 10,
119
+ :LValue => 11,
120
+ :RValue => 12,
121
+ "(" => 13,
122
+ ")" => 14 }
123
+
124
+ racc_nt_base = 15
125
+
126
+ racc_use_result_var = true
127
+
128
+ Racc_arg = [
129
+ racc_action_table,
130
+ racc_action_check,
131
+ racc_action_default,
132
+ racc_action_pointer,
133
+ racc_goto_table,
134
+ racc_goto_check,
135
+ racc_goto_default,
136
+ racc_goto_pointer,
137
+ racc_nt_base,
138
+ racc_reduce_table,
139
+ racc_token_table,
140
+ racc_shift_n,
141
+ racc_reduce_n,
142
+ racc_use_result_var ]
143
+
144
+ Racc_token_to_s_table = [
145
+ "$end",
146
+ "error",
147
+ "Command",
148
+ "LiteralCommand",
149
+ "Argument",
150
+ "Heredoc",
151
+ "InternalEval",
152
+ "Separator",
153
+ "Conditional",
154
+ "Pipe",
155
+ "Redirection",
156
+ "LValue",
157
+ "RValue",
158
+ "\"(\"",
159
+ "\")\"",
160
+ "$start",
161
+ "program",
162
+ "stmts",
163
+ "stmt",
164
+ "pipeline",
165
+ "stmts2",
166
+ "command_w_heredoc",
167
+ "internal_eval",
168
+ "command_w_redirects",
169
+ "command_w_vars",
170
+ "command",
171
+ "vars",
172
+ "command2",
173
+ "args" ]
174
+
175
+ Racc_debug_parser = false
176
+
177
+ ##### State transition tables end #####
178
+
179
+ # reduce 0 omitted
180
+
181
+ # reduce 1 omitted
182
+
183
+ module_eval(<<'.,.,', 'grammar.y', 23)
184
+ def _reduce_2(val, _values, result)
185
+ result = StatementsNode.new(val[0], val[2])
186
+ result
187
+ end
188
+ .,.,
189
+
190
+ module_eval(<<'.,.,', 'grammar.y', 25)
191
+ def _reduce_3(val, _values, result)
192
+ result = StatementsNode.new(val[0])
193
+ result
194
+ end
195
+ .,.,
196
+
197
+ module_eval(<<'.,.,', 'grammar.y', 28)
198
+ def _reduce_4(val, _values, result)
199
+ result = ConditionalNode.new(val[1].value, val[0], val[2])
200
+ result
201
+ end
202
+ .,.,
203
+
204
+ # reduce 5 omitted
205
+
206
+ module_eval(<<'.,.,', 'grammar.y', 32)
207
+ def _reduce_6(val, _values, result)
208
+ result = PipelineNode.new(val[0], val[2])
209
+ result
210
+ end
211
+ .,.,
212
+
213
+ # reduce 7 omitted
214
+
215
+ module_eval(<<'.,.,', 'grammar.y', 36)
216
+ def _reduce_8(val, _values, result)
217
+ result = val[1]
218
+ result
219
+ end
220
+ .,.,
221
+
222
+ # reduce 9 omitted
223
+
224
+ # reduce 10 omitted
225
+
226
+ module_eval(<<'.,.,', 'grammar.y', 41)
227
+ def _reduce_11(val, _values, result)
228
+ val[0].heredoc = val[1] ; result = val[0]
229
+ result
230
+ end
231
+ .,.,
232
+
233
+ # reduce 12 omitted
234
+
235
+ module_eval(<<'.,.,', 'grammar.y', 45)
236
+ def _reduce_13(val, _values, result)
237
+ val[0].redirects << RedirectionNode.new(val[1].value, val[1].attrs[:target]) ; result = val[0]
238
+ result
239
+ end
240
+ .,.,
241
+
242
+ # reduce 14 omitted
243
+
244
+ # reduce 15 omitted
245
+
246
+ # reduce 16 omitted
247
+
248
+ module_eval(<<'.,.,', 'grammar.y', 51)
249
+ def _reduce_17(val, _values, result)
250
+ result = EnvWrapperNode.new(val[0], val[1])
251
+ result
252
+ end
253
+ .,.,
254
+
255
+ module_eval(<<'.,.,', 'grammar.y', 54)
256
+ def _reduce_18(val, _values, result)
257
+ val[0].add_var(val[1].value, val[2].value) ; result = val[0]
258
+ result
259
+ end
260
+ .,.,
261
+
262
+ module_eval(<<'.,.,', 'grammar.y', 56)
263
+ def _reduce_19(val, _values, result)
264
+ result = EnvNode.new(val[0].value, val[1].value)
265
+ result
266
+ end
267
+ .,.,
268
+
269
+ # reduce 20 omitted
270
+
271
+ module_eval(<<'.,.,', 'grammar.y', 61)
272
+ def _reduce_21(val, _values, result)
273
+ result = CommandNode.new(val[0].value)
274
+ result
275
+ end
276
+ .,.,
277
+
278
+ module_eval(<<'.,.,', 'grammar.y', 63)
279
+ def _reduce_22(val, _values, result)
280
+ result = CommandNode.new(val[0].value, val[1].flatten)
281
+ result
282
+ end
283
+ .,.,
284
+
285
+ module_eval(<<'.,.,', 'grammar.y', 65)
286
+ def _reduce_23(val, _values, result)
287
+ result = CommandNode.new(val[0].value, literal:true)
288
+ result
289
+ end
290
+ .,.,
291
+
292
+ module_eval(<<'.,.,', 'grammar.y', 67)
293
+ def _reduce_24(val, _values, result)
294
+ result = CommandNode.new(val[0].value, val[1].flatten, literal:true)
295
+ result
296
+ end
297
+ .,.,
298
+
299
+ module_eval(<<'.,.,', 'grammar.y', 70)
300
+ def _reduce_25(val, _values, result)
301
+ result = [val[0].value]
302
+ result
303
+ end
304
+ .,.,
305
+
306
+ module_eval(<<'.,.,', 'grammar.y', 72)
307
+ def _reduce_26(val, _values, result)
308
+ result = [val[0], val[1].value]
309
+ result
310
+ end
311
+ .,.,
312
+
313
+ module_eval(<<'.,.,', 'grammar.y', 75)
314
+ def _reduce_27(val, _values, result)
315
+ result = InternalEvalNode.new(val[0].value)
316
+ result
317
+ end
318
+ .,.,
319
+
320
+ def _reduce_none(val, _values, result)
321
+ val[0]
322
+ end
323
+
324
+ end # class ParserImpl
325
+ end # module Shell
326
+ end # module Yap
327
+
328
+
329
+ if $0 == __FILE__
330
+ $LOAD_PATH.unshift File.dirname(__FILE__) + "/lib/"
331
+ require 'yap/shell/parser/lexer'
332
+ require 'yap/shell/parser/nodes'
333
+ [
334
+ # "echo foo",
335
+ # "echo foo ; echo bar baz yep",
336
+ # "echo foo && echo bar baz yep",
337
+ # "echo foo && echo bar && ls foo && ls bar",
338
+ # "echo foo ; echo bar baz yep ; ls foo",
339
+ # "echo foo && echo bar ; ls baz",
340
+ # "echo foo && echo bar ; ls baz ; echo zach || echo gretchen",
341
+ # "echo foo | bar",
342
+ # "echo foo | bar && foo | bar",
343
+ # "foo && bar ; word || baz ; yep | grep -v foo",
344
+ # "( foo )",
345
+ # "( foo a b && bar c d )",
346
+ # "( foo a b && (bar c d | baz e f))",
347
+ # "((((foo))))",
348
+ # "foo -b -c ; (this ;that ;the; other ;thing) && yep",
349
+ # "foo -b -c ; (this ;that && other ;thing) && yep",
350
+ # "4 + 5",
351
+ # "!'hello' ; 4 - 4 && 10 + 3",
352
+ # "\\foo <<-EOT\nbar\nEOT",
353
+ # "ls | grep md | grep WISH",
354
+ # "(!upcase)",
355
+ # "echo foo > bar.txt",
356
+ # "ls -l > a.txt ; echo f 2> b.txt ; cat b &> c.txt ; du -sh 1>&2 1>hey.txt",
357
+ # "!Dir.chdir('..')",
358
+ # "FOO=123",
359
+ # "FOO=123 BAR=345",
360
+ # "FOO=abc bar=2314 car=14ab ls -l",
361
+ "FOO=abc BAR='hello world' ls -l ; CAR=f echo foo && say hi"
362
+ ].each do |src|
363
+ puts 'parsing:'
364
+ print src
365
+ puts
366
+ puts 'result:'
367
+ require 'pp'
368
+ ast = Yap::Shell::Parser.new.parse(src)
369
+ pp ast
370
+ end
371
+
372
+
373
+ # puts "---- Evaluating"
374
+ # require 'pry'
375
+ # binding.pry
376
+ # Evaluator.new.evaltree(ast)
377
+ end
@@ -689,8 +689,114 @@ describe Yap::Shell::Parser::Lexer do
689
689
  t(:Argument, "-l", lineno: 0)
690
690
  ]}
691
691
  end
692
+ end
693
+
694
+ describe "command substitution" do
695
+ describe "backticks can wrap simple commands: `pwd`" do
696
+ let(:str){ "`pwd`" }
697
+ it { should eq [
698
+ t(:BeginSubcommand, "`", lineno: 0),
699
+ t(:Command, "pwd", lineno: 0),
700
+ t(:EndSubcommand, "`", lineno: 0)
701
+ ]}
702
+ end
703
+
704
+ describe "backticks can wrap complex statements: `ls -al && foo bar || baz`" do
705
+ let(:str){ "`ls -al && foo bar || baz`" }
706
+ it { should eq [
707
+ t(:BeginSubcommand, "`", lineno: 0),
708
+ t(:Command,'ls', lineno: 0),
709
+ t(:Argument, '-al', lineno: 0),
710
+ t(:Conditional, '&&', lineno: 0),
711
+ t(:Command, 'foo', lineno: 0),
712
+ t(:Argument, 'bar', lineno: 0),
713
+ t(:Conditional, '||', lineno: 0),
714
+ t(:Command, 'baz', lineno: 0),
715
+ t(:EndSubcommand, "`", lineno: 0)
716
+ ]}
717
+ end
718
+
719
+ describe "backticks can appear as an argument: echo `pwd`" do
720
+ let(:str){ "echo `pwd`" }
721
+ it { should eq [
722
+ t(:Command,'echo', lineno: 0),
723
+ t(:BeginSubcommand, "`", lineno: 0),
724
+ t(:Command,'pwd', lineno: 0),
725
+ t(:EndSubcommand, "`", lineno: 0)
726
+ ]}
727
+ end
692
728
 
729
+ describe "backticks can appear as a complex argument: echo `pwd && foo bar || baz ; yep` ; hello" do
730
+ let(:str){ "echo `pwd && foo bar || baz ; yep` ; hello" }
731
+ it { should eq [
732
+ t(:Command,'echo', lineno: 0),
733
+ t(:BeginSubcommand, "`", lineno: 0),
734
+ t(:Command,'pwd', lineno: 0),
735
+ t(:Conditional, '&&', lineno: 0),
736
+ t(:Command, 'foo', lineno: 0),
737
+ t(:Argument, 'bar', lineno: 0),
738
+ t(:Conditional, '||', lineno: 0),
739
+ t(:Command, 'baz', lineno: 0),
740
+ t(:Separator, ";", lineno: 0),
741
+ t(:Command, 'yep', lineno: 0),
742
+ t(:EndSubcommand, "`", lineno: 0),
743
+ t(:Separator, ";", lineno: 0),
744
+ t(:Command, "hello", lineno: 0)
745
+ ]}
746
+ end
693
747
 
748
+ describe "dollar-sign paren can wrap simple commands: $(pwd)" do
749
+ let(:str){ "$(pwd)" }
750
+ it { should eq [
751
+ t(:BeginSubcommand, "$(", lineno: 0),
752
+ t(:Command, "pwd", lineno: 0),
753
+ t(:EndSubcommand, ")", lineno: 0)
754
+ ]}
755
+ end
756
+
757
+ describe "dollar-sign paren can wrap complex statements: $(ls -al && foo bar || baz)" do
758
+ let(:str){ "`ls -al && foo bar || baz`" }
759
+ it { should eq [
760
+ t(:BeginSubcommand, "`", lineno: 0),
761
+ t(:Command,'ls', lineno: 0),
762
+ t(:Argument, '-al', lineno: 0),
763
+ t(:Conditional, '&&', lineno: 0),
764
+ t(:Command, 'foo', lineno: 0),
765
+ t(:Argument, 'bar', lineno: 0),
766
+ t(:Conditional, '||', lineno: 0),
767
+ t(:Command, 'baz', lineno: 0),
768
+ t(:EndSubcommand, "`", lineno: 0)
769
+ ]}
770
+ end
771
+
772
+ describe "dollar-sign paren can appear as an argument: echo $(pwd)" do
773
+ let(:str){ "echo $(pwd)" }
774
+ it { should eq [
775
+ t(:Command,'echo', lineno: 0),
776
+ t(:BeginSubcommand, "$(", lineno: 0),
777
+ t(:Command,'pwd', lineno: 0),
778
+ t(:EndSubcommand, ")", lineno: 0)
779
+ ]}
780
+ end
781
+
782
+ describe "dollar-sign paren can appear as a complex argument: echo $(pwd && foo bar || baz ; yep) ; hello" do
783
+ let(:str){ "echo $(pwd && foo bar || baz ; yep) ; hello" }
784
+ it { should eq [
785
+ t(:Command,'echo', lineno: 0),
786
+ t(:BeginSubcommand, "$(", lineno: 0),
787
+ t(:Command,'pwd', lineno: 0),
788
+ t(:Conditional, '&&', lineno: 0),
789
+ t(:Command, 'foo', lineno: 0),
790
+ t(:Argument, 'bar', lineno: 0),
791
+ t(:Conditional, '||', lineno: 0),
792
+ t(:Command, 'baz', lineno: 0),
793
+ t(:Separator, ";", lineno: 0),
794
+ t(:Command, 'yep', lineno: 0),
795
+ t(:EndSubcommand, ")", lineno: 0),
796
+ t(:Separator, ";", lineno: 0),
797
+ t(:Command, "hello", lineno: 0)
798
+ ]}
799
+ end
694
800
 
695
801
  end
696
802
 
@@ -9,13 +9,13 @@ Gem::Specification.new do |spec|
9
9
  spec.version = Yap::Shell::Parser::VERSION
10
10
  spec.authors = ["Zach Dennis"]
11
11
  spec.email = ["zach.dennis@gmail.com"]
12
- spec.summary = %q{The parser for the yap shell.}
13
- spec.description = %q{The parser for the yap shell.}
14
- spec.homepage = ""
12
+ spec.summary = %q{The parser for the yap shell}
13
+ spec.description = %q{The parser for the yap shell}
14
+ spec.homepage = "https://github.com/zdennis/yap-shell-parser"
15
15
  spec.license = "MIT"
16
16
 
17
17
  spec.files = `git ls-files -z`.split("\x0")
18
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ # spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
20
  spec.require_paths = ["lib"]
21
21
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yap-shell-parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zach Dennis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-20 00:00:00.000000000 Z
11
+ date: 2015-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,12 +52,10 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.2'
55
- description: The parser for the yap shell.
55
+ description: The parser for the yap shell
56
56
  email:
57
57
  - zach.dennis@gmail.com
58
- executables:
59
- - compile_debug_parser
60
- - compile_parser
58
+ executables: []
61
59
  extensions: []
62
60
  extra_rdoc_files: []
63
61
  files:
@@ -71,16 +69,16 @@ files:
71
69
  - bin/compile_debug_parser
72
70
  - bin/compile_parser
73
71
  - lib/tasks/gem.rake
74
- - lib/yap/shell.rb
75
72
  - lib/yap/shell/parser.rb
76
73
  - lib/yap/shell/parser/grammar.y
77
74
  - lib/yap/shell/parser/lexer.rb
78
75
  - lib/yap/shell/parser/nodes.rb
79
76
  - lib/yap/shell/parser/version.rb
77
+ - lib/yap/shell/parser_impl.rb
80
78
  - spec/spec_helper.rb
81
79
  - spec/yap/shell/lexer_spec.rb
82
80
  - yap-shell-parser.gemspec
83
- homepage: ''
81
+ homepage: https://github.com/zdennis/yap-shell-parser
84
82
  licenses:
85
83
  - MIT
86
84
  metadata: {}
@@ -103,7 +101,7 @@ rubyforge_project:
103
101
  rubygems_version: 2.4.3
104
102
  signing_key:
105
103
  specification_version: 4
106
- summary: The parser for the yap shell.
104
+ summary: The parser for the yap shell
107
105
  test_files:
108
106
  - spec/spec_helper.rb
109
107
  - spec/yap/shell/lexer_spec.rb
data/lib/yap/shell.rb DELETED
@@ -1,2 +0,0 @@
1
- module Yap::Shell
2
- end