racc 1.4.13 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -31,7 +31,7 @@ rule
31
31
  print 'cba'
32
32
  }
33
33
  | cont
34
-
34
+
35
35
  cont : A c2 B c2 C
36
36
 
37
37
  c2 : C C C C C
@@ -0,0 +1,622 @@
1
+ # Released under an MIT License (http://www.opensource.org/licenses/MIT)
2
+ # By Jay Strybis (https://github.com/unreal)
3
+
4
+ class TPPlus::Parser
5
+ token ASSIGN AT_SYM COMMENT JUMP IO_METHOD INPUT OUTPUT
6
+ token NUMREG POSREG VREG SREG TIME_SEGMENT ARG UALM
7
+ token MOVE DOT TO AT TERM OFFSET SKIP GROUP
8
+ token SEMICOLON NEWLINE STRING
9
+ token REAL DIGIT WORD EQUAL
10
+ token EEQUAL NOTEQUAL GTE LTE LT GT BANG
11
+ token PLUS MINUS STAR SLASH DIV AND OR MOD
12
+ token IF ELSE END UNLESS FOR IN WHILE
13
+ token WAIT_FOR WAIT_UNTIL TIMEOUT AFTER
14
+ token FANUC_USE SET_SKIP_CONDITION NAMESPACE
15
+ token CASE WHEN INDIRECT POSITION
16
+ token EVAL TIMER TIMER_METHOD RAISE ABORT
17
+ token POSITION_DATA TRUE_FALSE RUN TP_HEADER PAUSE
18
+ token LPAREN RPAREN COLON COMMA LBRACK RBRACK LBRACE RBRACE
19
+ token LABEL ADDRESS
20
+ token false
21
+
22
+ prechigh
23
+ right BANG
24
+ left STAR SLASH DIV MOD
25
+ left PLUS MINUS
26
+ left GT GTE LT LTE
27
+ left EEQUAL NOTEQUAL
28
+ left AND
29
+ left OR
30
+ right EQUAL
31
+ preclow
32
+
33
+ rule
34
+ program
35
+ #: statements { @interpreter.nodes = val[0].flatten }
36
+ : statements { @interpreter.nodes = val[0] }
37
+ |
38
+ ;
39
+
40
+
41
+ statements
42
+ : statement terminator {
43
+ result = [val[0]]
44
+ result << val[1] unless val[1].nil?
45
+ }
46
+ | statements statement terminator {
47
+ result = val[0] << val[1]
48
+ result << val[2] unless val[2].nil?
49
+ }
50
+ ;
51
+
52
+ block
53
+ : NEWLINE statements { result = val[1] }
54
+ ;
55
+
56
+ optional_newline
57
+ : NEWLINE
58
+ |
59
+ ;
60
+
61
+ statement
62
+ : comment
63
+ | definition
64
+ | namespace
65
+ #| assignment
66
+ | motion_statement
67
+ #| jump
68
+ #| io_method
69
+ | label_definition
70
+ | address
71
+ | conditional
72
+ | inline_conditional
73
+ | forloop
74
+ | while_loop
75
+ #| program_call
76
+ | use_statement
77
+ | set_skip_statement
78
+ | wait_statement
79
+ | case_statement
80
+ | fanuc_eval
81
+ | timer_method
82
+ | position_data
83
+ | raise
84
+ | tp_header_definition
85
+ | empty_stmt
86
+ | PAUSE { result = PauseNode.new }
87
+ | ABORT { result = AbortNode.new }
88
+ ;
89
+
90
+ empty_stmt
91
+ : NEWLINE { result = EmptyStmtNode.new() }
92
+ ;
93
+
94
+ tp_header_definition
95
+ : TP_HEADER EQUAL tp_header_value { result = HeaderNode.new(val[0],val[2]) }
96
+ ;
97
+
98
+ tp_header_value
99
+ : STRING
100
+ | TRUE_FALSE
101
+ ;
102
+
103
+ raise
104
+ : RAISE var_or_indirect { result = RaiseNode.new(val[1]) }
105
+ ;
106
+
107
+ timer_method
108
+ : TIMER_METHOD var_or_indirect { result = TimerMethodNode.new(val[0],val[1]) }
109
+ ;
110
+
111
+ fanuc_eval
112
+ : EVAL STRING { result = EvalNode.new(val[1]) }
113
+ ;
114
+
115
+ wait_statement
116
+ : WAIT_FOR LPAREN indirectable COMMA STRING RPAREN
117
+ { result = WaitForNode.new(val[2], val[4]) }
118
+ | WAIT_UNTIL LPAREN expression RPAREN
119
+ { result = WaitUntilNode.new(val[2], nil) }
120
+ | WAIT_UNTIL LPAREN expression RPAREN DOT wait_modifier
121
+ { result = WaitUntilNode.new(val[2],val[5]) }
122
+ | WAIT_UNTIL LPAREN expression RPAREN DOT wait_modifier DOT wait_modifier
123
+ { result = WaitUntilNode.new(val[2],val[5].merge(val[7])) }
124
+ ;
125
+
126
+ wait_modifier
127
+ : timeout_modifier
128
+ | after_modifier
129
+ ;
130
+
131
+ timeout_modifier
132
+ : swallow_newlines TIMEOUT LPAREN label RPAREN
133
+ { result = { label: val[3] } }
134
+ ;
135
+
136
+ after_modifier
137
+ : swallow_newlines AFTER LPAREN indirectable COMMA STRING RPAREN
138
+ { result = { timeout: [val[3],val[5]] } }
139
+ ;
140
+
141
+ label
142
+ : LABEL { result = val[0] }
143
+ ;
144
+
145
+ use_statement
146
+ : FANUC_USE indirectable { result = UseNode.new(val[0],val[1]) }
147
+ ;
148
+
149
+ # set_skip_condition x
150
+ set_skip_statement
151
+ : SET_SKIP_CONDITION expression { result = SetSkipNode.new(val[1]) }
152
+ ;
153
+
154
+ program_call
155
+ : WORD LPAREN args RPAREN { result = CallNode.new(val[0],val[2]) }
156
+ | RUN WORD LPAREN args RPAREN { result = CallNode.new(val[1],val[3],async: true) }
157
+ ;
158
+
159
+ args
160
+ : arg { result = [val[0]] }
161
+ | args COMMA arg { result = val[0] << val[2] }
162
+ | { result = [] }
163
+ ;
164
+
165
+ arg
166
+ : number
167
+ | var
168
+ | string
169
+ | address
170
+ ;
171
+
172
+ string
173
+ : STRING { result = StringNode.new(val[0]) }
174
+ ;
175
+
176
+ io_method
177
+ : IO_METHOD var_or_indirect { result = IOMethodNode.new(val[0],val[1]) }
178
+ | IO_METHOD LPAREN var_or_indirect RPAREN
179
+ { result = IOMethodNode.new(val[0],val[2]) }
180
+ | IO_METHOD LPAREN var_or_indirect COMMA number COMMA STRING RPAREN
181
+ { result = IOMethodNode.new(val[0],val[2],{ pulse_time: val[4], pulse_units: val[6] }) }
182
+ ;
183
+
184
+ var_or_indirect
185
+ : var
186
+ | indirect_thing
187
+ ;
188
+
189
+
190
+ jump
191
+ : JUMP label { result = JumpNode.new(val[1]) }
192
+ ;
193
+
194
+ conditional
195
+ : IF expression block else_block END
196
+ { result = ConditionalNode.new("if",val[1],val[2],val[3]) }
197
+ | UNLESS expression block else_block END
198
+ { result = ConditionalNode.new("unless",val[1],val[2],val[3]) }
199
+ ;
200
+
201
+ forloop
202
+ : FOR var IN LPAREN minmax_val TO minmax_val RPAREN block END
203
+ { result = ForNode.new(val[1],val[4],val[6],val[8]) }
204
+ ;
205
+
206
+ while_loop
207
+ : WHILE expression block END { result = WhileNode.new(val[1],val[2]) }
208
+ ;
209
+
210
+ minmax_val
211
+ : integer
212
+ | var
213
+ ;
214
+
215
+ namespace
216
+ : NAMESPACE WORD block END { result = NamespaceNode.new(val[1],val[2]) }
217
+ ;
218
+
219
+ case_statement
220
+ : CASE var swallow_newlines
221
+ case_conditions
222
+ case_else
223
+ END { result = CaseNode.new(val[1],val[3],val[4]) }
224
+ ;
225
+
226
+ case_conditions
227
+ : case_condition { result = val }
228
+ | case_conditions case_condition
229
+ { result = val[0] << val[1] << val[2] }
230
+ ;
231
+
232
+ case_condition
233
+ : WHEN case_allowed_condition swallow_newlines case_allowed_statement
234
+ terminator { result = CaseConditionNode.new(val[1],val[3]) }
235
+ ;
236
+
237
+ case_allowed_condition
238
+ : number
239
+ | var
240
+ ;
241
+
242
+ case_else
243
+ : ELSE swallow_newlines case_allowed_statement terminator
244
+ { result = CaseConditionNode.new(nil,val[2]) }
245
+ |
246
+ ;
247
+
248
+ case_allowed_statement
249
+ : program_call
250
+ | jump
251
+ ;
252
+
253
+ inline_conditional
254
+ : inlineable
255
+ | inlineable IF expression { result = InlineConditionalNode.new(val[1], val[2], val[0]) }
256
+ | inlineable UNLESS expression { result = InlineConditionalNode.new(val[1], val[2], val[0]) }
257
+ ;
258
+
259
+ inlineable
260
+ : jump
261
+ | assignment
262
+ | io_method
263
+ | program_call
264
+ ;
265
+
266
+ else_block
267
+ : ELSE block { result = val[1] }
268
+ | { result = [] }
269
+ ;
270
+
271
+ motion_statement
272
+ : MOVE DOT swallow_newlines TO LPAREN var RPAREN motion_modifiers
273
+ { result = MotionNode.new(val[0],val[5],val[7]) }
274
+ ;
275
+
276
+ motion_modifiers
277
+ : motion_modifier { result = val }
278
+ | motion_modifiers motion_modifier
279
+ { result = val[0] << val[1] }
280
+ ;
281
+
282
+ motion_modifier
283
+ : DOT swallow_newlines AT LPAREN speed RPAREN
284
+ { result = SpeedNode.new(val[4]) }
285
+ | DOT swallow_newlines TERM LPAREN valid_terminations RPAREN
286
+ { result = TerminationNode.new(val[4]) }
287
+ | DOT swallow_newlines OFFSET LPAREN var RPAREN
288
+ { result = OffsetNode.new(val[2],val[4]) }
289
+ | DOT swallow_newlines TIME_SEGMENT LPAREN time COMMA time_seg_actions RPAREN
290
+ { result = TimeNode.new(val[2],val[4],val[6]) }
291
+ | DOT swallow_newlines SKIP LPAREN label optional_lpos_arg RPAREN
292
+ { result = SkipNode.new(val[4],val[5]) }
293
+ ;
294
+
295
+ valid_terminations
296
+ : integer
297
+ | var
298
+ | MINUS DIGIT {
299
+ raise Racc::ParseError, sprintf("\ninvalid termination type: (%s)", val[1]) if val[1] != 1
300
+
301
+ result = DigitNode.new(val[1].to_i * -1)
302
+ }
303
+ ;
304
+
305
+ optional_lpos_arg
306
+ : COMMA var { result = val[1] }
307
+ |
308
+ ;
309
+
310
+ indirectable
311
+ : number
312
+ | var
313
+ ;
314
+
315
+ time_seg_actions
316
+ : program_call
317
+ | io_method
318
+ ;
319
+
320
+ time
321
+ : var
322
+ | number
323
+ ;
324
+
325
+ speed
326
+ : indirectable COMMA STRING { result = { speed: val[0], units: val[2] } }
327
+ | STRING { result = { speed: val[0], units: nil } }
328
+ ;
329
+
330
+ label_definition
331
+ : label { result = LabelDefinitionNode.new(val[0]) }#@interpreter.add_label(val[1]) }
332
+ ;
333
+
334
+ definition
335
+ : WORD ASSIGN definable { result = DefinitionNode.new(val[0],val[2]) }
336
+ ;
337
+
338
+ assignment
339
+ : var_or_indirect EQUAL expression { result = AssignmentNode.new(val[0],val[2]) }
340
+ | var_or_indirect PLUS EQUAL expression { result = AssignmentNode.new(
341
+ val[0],
342
+ ExpressionNode.new(val[0],"+",val[3])
343
+ )
344
+ }
345
+ | var_or_indirect MINUS EQUAL expression { result = AssignmentNode.new(
346
+ val[0],
347
+ ExpressionNode.new(val[0],"-",val[3])
348
+ )
349
+ }
350
+ ;
351
+
352
+ var
353
+ : var_without_namespaces
354
+ | var_with_namespaces
355
+ ;
356
+
357
+ var_without_namespaces
358
+ : WORD { result = VarNode.new(val[0]) }
359
+ | WORD var_method_modifiers { result = VarMethodNode.new(val[0],val[1]) }
360
+ ;
361
+
362
+ var_with_namespaces
363
+ : namespaces var_without_namespaces
364
+ { result = NamespacedVarNode.new(val[0],val[1]) }
365
+ ;
366
+
367
+ var_method_modifiers
368
+ : var_method_modifier { result = val[0] }
369
+ | var_method_modifiers var_method_modifier
370
+ { result = val[0].merge(val[1]) }
371
+ ;
372
+
373
+ var_method_modifier
374
+ : DOT swallow_newlines WORD { result = { method: val[2] } }
375
+ | DOT swallow_newlines GROUP LPAREN integer RPAREN
376
+ { result = { group: val[4] } }
377
+ ;
378
+
379
+ namespaces
380
+ : ns { result = [val[0]] }
381
+ | namespaces ns { result = val[0] << val[1] }
382
+ ;
383
+
384
+ ns
385
+ : WORD COLON COLON { result = val[0] }
386
+ ;
387
+
388
+
389
+ expression
390
+ : unary_expression
391
+ | binary_expression
392
+ ;
393
+
394
+ unary_expression
395
+ : factor { result = val[0] }
396
+ | address
397
+ | BANG factor { result = ExpressionNode.new(val[1], "!", nil) }
398
+ ;
399
+
400
+ binary_expression
401
+ : expression operator expression
402
+ { result = ExpressionNode.new(val[0], val[1], val[2]) }
403
+ ;
404
+
405
+ operator
406
+ : EEQUAL { result = "==" }
407
+ | NOTEQUAL { result = "<>" }
408
+ | LT { result = "<" }
409
+ | GT { result = ">" }
410
+ | GTE { result = ">=" }
411
+ | LTE { result = "<=" }
412
+ | PLUS { result = "+" }
413
+ | MINUS { result = "-" }
414
+ | OR { result = "||" }
415
+ | STAR { result = "*" }
416
+ | SLASH { result = "/" }
417
+ | DIV { result = "DIV" }
418
+ | MOD { result = "%" }
419
+ | AND { result = "&&" }
420
+ ;
421
+
422
+ factor
423
+ : number
424
+ | signed_number
425
+ | var
426
+ | indirect_thing
427
+ | paren_expr
428
+ ;
429
+
430
+ paren_expr
431
+ : LPAREN expression RPAREN { result = ParenExpressionNode.new(val[1]) }
432
+ ;
433
+
434
+ indirect_thing
435
+ : INDIRECT LPAREN STRING COMMA indirectable RPAREN
436
+ { result = IndirectNode.new(val[2].to_sym, val[4]) }
437
+ ;
438
+
439
+ signed_number
440
+ : sign DIGIT {
441
+ val[1] = val[1].to_i * -1 if val[0] == "-"
442
+ result = DigitNode.new(val[1])
443
+ }
444
+ | sign REAL { val[1] = val[1].to_f * -1 if val[0] == "-"; result = RealNode.new(val[1]) }
445
+ ;
446
+
447
+ sign
448
+ : MINUS { result = "-" }
449
+ ;
450
+
451
+ number
452
+ : integer
453
+ | REAL { result = RealNode.new(val[0]) }
454
+ ;
455
+
456
+ integer
457
+ : DIGIT { result = DigitNode.new(val[0]) }
458
+ ;
459
+
460
+ definable
461
+ : numreg
462
+ | output
463
+ | input
464
+ | posreg
465
+ | position
466
+ | vreg
467
+ | number
468
+ | signed_number
469
+ | argument
470
+ | timer
471
+ | ualm
472
+ | sreg
473
+ ;
474
+
475
+
476
+ sreg
477
+ : SREG LBRACK DIGIT RBRACK { result = StringRegisterNode.new(val[2].to_i) }
478
+ ;
479
+
480
+ ualm
481
+ : UALM LBRACK DIGIT RBRACK { result = UserAlarmNode.new(val[2].to_i) }
482
+ ;
483
+
484
+ timer
485
+ : TIMER LBRACK DIGIT RBRACK { result = TimerNode.new(val[2].to_i) }
486
+ ;
487
+
488
+ argument
489
+ : ARG LBRACK DIGIT RBRACK { result = ArgumentNode.new(val[2].to_i) }
490
+ ;
491
+
492
+ vreg
493
+ : VREG LBRACK DIGIT RBRACK { result = VisionRegisterNode.new(val[2].to_i) }
494
+ ;
495
+
496
+ position
497
+ : POSITION LBRACK DIGIT RBRACK { result = PositionNode.new(val[2].to_i) }
498
+ ;
499
+
500
+ numreg
501
+ : NUMREG LBRACK DIGIT RBRACK { result = NumregNode.new(val[2].to_i) }
502
+ ;
503
+
504
+ posreg
505
+ : POSREG LBRACK DIGIT RBRACK { result = PosregNode.new(val[2].to_i) }
506
+ ;
507
+
508
+ output
509
+ : OUTPUT LBRACK DIGIT RBRACK { result = IONode.new(val[0], val[2].to_i) }
510
+ ;
511
+
512
+ input
513
+ : INPUT LBRACK DIGIT RBRACK { result = IONode.new(val[0], val[2].to_i) }
514
+ ;
515
+
516
+ address
517
+ : ADDRESS { result = AddressNode.new(val[0]) }
518
+ ;
519
+
520
+ comment
521
+ : COMMENT { result = CommentNode.new(val[0]) }
522
+ ;
523
+
524
+ terminator
525
+ : NEWLINE { result = TerminatorNode.new }
526
+ | comment optional_newline { result = val[0] }
527
+ # ^-- consume newlines or else we will get an extra space from EmptyStmt in the output
528
+ | false
529
+ |
530
+ ;
531
+
532
+ swallow_newlines
533
+ : NEWLINE { result = TerminatorNode.new }
534
+ |
535
+ ;
536
+
537
+ position_data
538
+ : POSITION_DATA sn hash sn END
539
+ { result = PositionDataNode.new(val[2]) }
540
+ ;
541
+
542
+ sn
543
+ : swallow_newlines
544
+ ;
545
+
546
+ hash
547
+ : LBRACE sn hash_attributes sn RBRACE { result = val[2] }
548
+ | LBRACE sn RBRACE { result = {} }
549
+ ;
550
+
551
+ hash_attributes
552
+ : hash_attribute { result = val[0] }
553
+ | hash_attributes COMMA sn hash_attribute
554
+ { result = val[0].merge(val[3]) }
555
+ ;
556
+
557
+ hash_attribute
558
+ : STRING COLON hash_value { result = { val[0].to_sym => val[2] } }
559
+ ;
560
+
561
+ hash_value
562
+ : STRING
563
+ | hash
564
+ | array
565
+ | optional_sign DIGIT { val[1] = val[1].to_i * -1 if val[0] == "-"; result = val[1] }
566
+ | optional_sign REAL { val[1] = val[1].to_f * -1 if val[0] == "-"; result = val[1] }
567
+ | TRUE_FALSE { result = val[0] == "true" }
568
+ ;
569
+
570
+ optional_sign
571
+ : sign
572
+ |
573
+ ;
574
+
575
+ array
576
+ : LBRACK sn array_values sn RBRACK { result = val[2] }
577
+ ;
578
+
579
+ array_values
580
+ : array_value { result = val }
581
+ | array_values COMMA sn array_value { result = val[0] << val[3] }
582
+ ;
583
+
584
+ array_value
585
+ : hash_value
586
+ ;
587
+
588
+
589
+ end
590
+
591
+ ---- inner
592
+
593
+ include TPPlus::Nodes
594
+
595
+ attr_reader :interpreter
596
+ def initialize(scanner, interpreter = TPPlus::Interpreter.new)
597
+ @scanner = scanner
598
+ @interpreter = interpreter
599
+ super()
600
+ end
601
+
602
+ def next_token
603
+ t = @scanner.next_token
604
+ @interpreter.line_count += 1 if t && t[0] == :NEWLINE
605
+
606
+ #puts t.inspect
607
+ t
608
+ end
609
+
610
+ def parse
611
+ #@yydebug =true
612
+
613
+ do_parse
614
+ @interpreter
615
+ end
616
+
617
+ def on_error(t, val, vstack)
618
+ raise ParseError, sprintf("Parse error on line #{@scanner.tok_line} column #{@scanner.tok_col}: %s (%s)",
619
+ val.inspect, token_to_str(t) || '?')
620
+ end
621
+
622
+ class ParseError < StandardError ; end