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