yap-shell-parser 0.0.1 → 0.0.3

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.
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