~ubuntu-branches/ubuntu/wily/puppet/wily

« back to all changes in this revision

Viewing changes to lib/puppet/pops/parser/grammar.ra

  • Committer: Package Import Robot
  • Author(s): Stig Sandbeck Mathisen
  • Date: 2014-04-17 14:50:28 UTC
  • mfrom: (3.1.59 sid)
  • Revision ID: package-import@ubuntu.com-20140417145028-j3p3dwvp8ggpzvaf
Tags: 3.5.1-1
ImportedĀ upstreamĀ releaseĀ 3.5.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# vim: syntax=ruby
2
 
 
3
 
# Parser using the Pops model
4
 
# This grammar is a half step between the current 3.1. grammar and egrammar.
5
 
# FIXME! Keep as reference until egrammar is proven to work.
6
 
 
7
 
class Puppet::Pops::Impl::Parser::Parser
8
 
 
9
 
token STRING DQPRE DQMID DQPOST
10
 
token LBRACK  RBRACK LBRACE RBRACE SYMBOL FARROW COMMA TRUE
11
 
token FALSE EQUALS APPENDS LESSEQUAL NOTEQUAL DOT COLON LLCOLLECT RRCOLLECT
12
 
token QMARK LPAREN RPAREN ISEQUAL GREATEREQUAL GREATERTHAN LESSTHAN
13
 
token IF ELSE IMPORT DEFINE ELSIF VARIABLE CLASS INHERITS NODE BOOLEAN
14
 
token NAME SEMIC CASE DEFAULT AT LCOLLECT RCOLLECT CLASSREF
15
 
token NOT OR AND UNDEF PARROW PLUS MINUS TIMES DIV LSHIFT RSHIFT UMINUS
16
 
token MATCH NOMATCH REGEX IN_EDGE OUT_EDGE IN_EDGE_SUB OUT_EDGE_SUB
17
 
token IN UNLESS PIPE
18
 
token LAMBDA
19
 
 
20
 
prechigh
21
 
  left DOT
22
 
#  left LBRACE
23
 
#  left LCOLLECT LLCOLLECT
24
 
  right NOT
25
 
  nonassoc UMINUS
26
 
  left  IN MATCH NOMATCH
27
 
  left  TIMES DIV
28
 
  left  MINUS PLUS
29
 
  left  LSHIFT RSHIFT
30
 
  left  NOTEQUAL ISEQUAL
31
 
  left  GREATEREQUAL GREATERTHAN LESSTHAN LESSEQUAL
32
 
  left  AND
33
 
  left  OR
34
 
#  left  IN_EDGE OUT_EDGE IN_EDGE_SUB OUT_EDGE_SUB
35
 
preclow
36
 
 
37
 
rule
38
 
# Produces [Model::BlockExpression, Model::Expression, nil] depending on multiple statements, single statement or empty
39
 
program
40
 
  : statements { result = Factory.block_or_expression(*val[0]) }
41
 
  | nil
42
 
 
43
 
# Change may have issues with nil; i.e. program is a sequence of nils/nops
44
 
# Simplified from original which had validation for top level constructs - see statement rule
45
 
# Produces Array<Model::Expression>
46
 
statements
47
 
  : statement            { result = [val[0]]}
48
 
  | statements statement { result = val[0].push val[1] }
49
 
 
50
 
# Removed validation construct regarding "top level statements" as it did not seem to catch all problems
51
 
# and relied on a "top-level-ness" encoded in the abstract syntax tree objects
52
 
#
53
 
# The main list of valid statements
54
 
# Produces Model::Expression
55
 
#
56
 
statement
57
 
  : resource
58
 
  | virtual_resource
59
 
  | collection
60
 
  | assignment
61
 
  | casestatement
62
 
  | if_expression
63
 
  | unless_expression
64
 
  | import
65
 
  | call_named_function
66
 
  | definition
67
 
  | hostclass
68
 
  | nodedef
69
 
  | resource_override
70
 
  | append
71
 
  | relationship
72
 
  | call_method_with_lambda
73
 
 
74
 
keyword
75
 
 : AND
76
 
 | CASE
77
 
 | CLASS
78
 
 | DEFAULT
79
 
 | DEFINE
80
 
 | ELSE
81
 
 | ELSIF
82
 
 | IF
83
 
 | IN
84
 
 | IMPORT
85
 
 | INHERITS
86
 
 | NODE
87
 
 | OR
88
 
 | UNDEF
89
 
 | UNLESS
90
 
 
91
 
# Produces Model::RelationshipExpression
92
 
relationship
93
 
  : relationship_side edge relationship_side { result = val[0].relop(val[1][:value], val[2]); loc result, val[1] }
94
 
  | relationship edge relationship_side      { result = val[0].relop(val[1][:value], val[2]); loc result, val[1] }
95
 
 
96
 
# Produces Model::Expression
97
 
relationship_side
98
 
  : resource
99
 
  | resourceref
100
 
  | collection
101
 
  | variable
102
 
  | quotedtext
103
 
  | selector
104
 
  | casestatement
105
 
  | hasharrayaccesses
106
 
 
107
 
# Produces String
108
 
edge
109
 
  : IN_EDGE
110
 
  | OUT_EDGE
111
 
  | IN_EDGE_SUB
112
 
  | OUT_EDGE_SUB
113
 
 
114
 
# Produces Model::CallNamedFunctionExpression
115
 
call_named_function
116
 
  : NAME LPAREN expressions RPAREN       { result = Factory.CALL_NAMED(val[0][:value], false, val[2]) ; loc result, val[0], val[3] }
117
 
  | NAME LPAREN expressions COMMA RPAREN { result = Factory.CALL_NAMED(val[0][:value], false, val[2]) ; loc result, val[0], val[4] }            
118
 
  | NAME LPAREN RPAREN                   { result = Factory.CALL_NAMED(val[0][:value], false, [])     ; loc result, val[0], val[2] }
119
 
  | NAME func_call_args                  { result = Factory.CALL_NAMED(val[0][:value], false, val[1]) ; loc result, val[0] }
120
 
 
121
 
call_method_with_lambda
122
 
  : call_method        { result = val[0] }
123
 
  | call_method lambda { result = val[0]; val[0].lambda = val[1] }
124
 
  
125
 
call_method
126
 
  : named_access LPAREN expressions RPAREN { result = Factory.CALL_METHOD(val[0], val[2]); loc result, val[1], val[3] }
127
 
  | named_access LPAREN RPAREN             { result = Factory.CALL_METHOD(val[0], []); loc result, val[1], val[3] }
128
 
  | named_access                           { result = Factory.CALL_METHOD(val[0], []); loc result, val[0] }
129
 
 
130
 
named_access
131
 
  : named_access_lval DOT NAME {
132
 
      result = val[0].dot(Factory.fqn(val[2][:value]))
133
 
      loc result, val[1], val[2]
134
 
    }
135
 
  
136
 
# Obviously not ideal, it is not possible to use literal array or hash as lhs
137
 
# These must be assigned to a variable - this is also an issue in other places
138
 
#
139
 
named_access_lval
140
 
  : variable 
141
 
  | hasharrayaccesses
142
 
  | selector
143
 
  | quotedtext
144
 
  | call_named_rval_function
145
 
    
146
 
lambda
147
 
  : LAMBDA lambda_parameter_list statements RBRACE {
148
 
      result = Factory.LAMBDA(val[1], val[2])
149
 
      loc result, val[0], val[3]
150
 
    }
151
 
  | LAMBDA lambda_parameter_list RBRACE {
152
 
      result = Factory.LAMBDA(val[1], nil)
153
 
      loc result, val[0], val[2]
154
 
    }
155
 
# Produces Array<Model::Parameter>
156
 
lambda_parameter_list
157
 
  : PIPE PIPE             { result = [] }
158
 
  | PIPE parameters endcomma PIPE { result = val[1] }
159
 
  
160
 
# Produces Array<Model::Expression>
161
 
func_call_args
162
 
  : rvalue                      { result = [val[0]] }
163
 
  | func_call_args COMMA rvalue { result = val[0].push(val[2]) }
164
 
 
165
 
# Produces Array<Model::Expression>
166
 
expressions
167
 
  : expression                   { result = [val[0]] }
168
 
  | expressions comma expression { result = val[0].push(val[2]) }
169
 
 
170
 
 
171
 
# Produces [Model::ResourceExpression, Model::ResourceDefaultsExpression]
172
 
resource
173
 
  : classname LBRACE resourceinstances endsemi RBRACE {
174
 
      result = Factory.RESOURCE(Factory.fqn(token_text(val[0])), val[2])
175
 
      loc result, val[0], val[4]
176
 
    }
177
 
  | classname LBRACE attribute_operations endcomma RBRACE {
178
 
      # This is a deprecated syntax.
179
 
      # It also fails hard - TODO: create model and validate this case
180
 
      error "All resource specifications require names"
181
 
    }
182
 
  | type LBRACE attribute_operations endcomma RBRACE {
183
 
      # a defaults setting for a type
184
 
      result = Factory.RESOURCE_DEFAULTS(val[0], val[2])
185
 
      loc result, val[0], val[4]
186
 
    }
187
 
 
188
 
# Override a value set elsewhere in the configuration.
189
 
# Produces Model::ResourceOverrideExpression
190
 
resource_override
191
 
  : resourceref LBRACE attribute_operations endcomma RBRACE {
192
 
      @lexer.commentpop
193
 
      result = Factory.RESOURCE_OVERRIDE(val[0], val[2])
194
 
      loc result, val[0], val[4]
195
 
    }
196
 
 
197
 
# Exported and virtual resources; these don't get sent to the client
198
 
# unless they get collected elsewhere in the db.
199
 
# The original had validation here; checking if storeconfigs is on; this is moved to a validation step
200
 
# Also, validation was performed if an attempt was made to virtualize or export a resource defaults
201
 
# this is also now deferred to validation 
202
 
# Produces [Model::ResourceExpression, Model::ResourceDefaultsExpression]
203
 
virtual_resource
204
 
  :  at resource { 
205
 
       val[1].form = val[0] # :virtual, :exported, (or :regular)
206
 
       result = val[1] 
207
 
     }
208
 
 
209
 
# Produces Symbol corresponding to resource form
210
 
at
211
 
  : AT    { result = :virtual  }
212
 
  | AT AT { result = :exported }
213
 
 
214
 
# A collection statement.  Currently supports no arguments at all, but eventually
215
 
# will, I assume.
216
 
#
217
 
# Produces Model::CollectExpression
218
 
#
219
 
collection
220
 
  : type collect_query LBRACE attribute_operations endcomma RBRACE {
221
 
      @lexer.commentpop
222
 
      result = Factory.COLLECT(val[0].value.downcase, val[1], val[3])
223
 
      loc result, val[0], val[5]
224
 
    }
225
 
  | type collect_query {
226
 
      result = Factory.COLLECT(val[0].value.downcase, val[1], [])
227
 
      loc result, val[0], val[1]
228
 
    }
229
 
 
230
 
collect_query
231
 
  : LCOLLECT  optional_query RCOLLECT  { result = Factory.VIRTUAL_QUERY(val[1])   ; loc result, val[0], val[2] }
232
 
  | LLCOLLECT optional_query RRCOLLECT { result = Factory.EXPORTED_QUERY(val[1])  ; loc result, val[0], val[2] }
233
 
 
234
 
# ORIGINAL COMMENT: A mini-language for handling collection comparisons.  This is organized
235
 
#                   to avoid the need for precedence indications.
236
 
# (New implementation is slightly different; and when finished, it may be possible to streamline the
237
 
#  grammar - the difference is mostly in evaluation, not in grammar)
238
 
#
239
 
optional_query
240
 
  : nil
241
 
  | query
242
 
 
243
 
# ORIGINAL: Had a weird list structure where AND and OR where at the same level, and hence, there was the
244
 
#           need to keep track of where parenthesis were (to get order correct).
245
 
246
 
# This is now not needed as AND has higher precedence than OR, and parenthesis are low in precedence
247
 
 
248
 
query
249
 
  : predicate_lval ISEQUAL  expression { result = (val[0] == val[2])  ; loc result, val[1] } 
250
 
  | predicate_lval NOTEQUAL expression { result = (val[0].ne(val[2])) ; loc result, val[1] }
251
 
  | LPAREN query RPAREN                { result = val[1] }
252
 
  | query AND query                    { result = val[0].and(val[2]) ; loc result, val[1] }
253
 
  | query OR  query                    { result = val[0].or(val[2])  ; loc result, val[1] }
254
 
 
255
 
 
256
 
# Produces Model::VariableExpression, or Model::QualifiedName
257
 
predicate_lval
258
 
  : variable
259
 
  | name
260
 
 
261
 
resourceinst
262
 
  : resourcename COLON attribute_operations endcomma { result = Factory.RESOURCE_BODY(val[0], val[2]) }
263
 
 
264
 
resourceinstances
265
 
  : resourceinst                         { result = [val[0]] }
266
 
  | resourceinstances SEMIC resourceinst { result = val[0].push val[2] }
267
 
 
268
 
 
269
 
resourcename
270
 
  : quotedtext
271
 
  | name
272
 
  | type
273
 
  | selector
274
 
  | variable
275
 
  | array
276
 
  | hasharrayaccesses
277
 
 
278
 
# Assignment, only assignment to variable is legal, but parser builds expression for [] = anyway to 
279
 
# enable a better error message
280
 
assignment
281
 
  : VARIABLE EQUALS expression { result = Factory.var(Factory.fqn(val[0][:value])).set(val[2]) ; loc result, val[1] }
282
 
  | hasharrayaccess EQUALS expression { result val[0].set(val[2]); loc result, val[1] }
283
 
 
284
 
append
285
 
  : VARIABLE APPENDS expression { result = Factory.var(val[0][:value]).plus_set(val[1]) ; loc result, val[1] }
286
 
 
287
 
# Produces Array<Model::AttributeOperation>
288
 
attribute_operations
289
 
  :                                                { result = [] }
290
 
  | attribute_operation                            { result = [val[0]] }
291
 
  | attribute_operations COMMA attribute_operation { result = val[0].push(val[2]) }
292
 
 
293
 
# Produces String
294
 
attribute_name
295
 
  : NAME 
296
 
  | keyword 
297
 
  | BOOLEAN
298
 
 
299
 
# Several grammar issues here: the addparam did not allow keyword and booleans as names.
300
 
# In this version, the wrong combinations are validated instead of producing syntax errors
301
 
# (Can give nicer error message +> is not applicable to...)
302
 
# WAT - Boolean as attribute name? 
303
 
# Produces Model::AttributeOperation
304
 
#
305
 
attribute_operation
306
 
  : attribute_name FARROW expression {
307
 
      result = Factory.ATTRIBUTE_OP(val[0][:value], :'=>', val[2])
308
 
      loc result, val[0], val[2]
309
 
    }
310
 
  | attribute_name PARROW expression {
311
 
      result = Factory.ATTRIBUTE_OP(val[0][:value], :'+>', val[2])
312
 
      loc result, val[0], val[2]
313
 
    }
314
 
 
315
 
# Produces Model::CallNamedFunction
316
 
call_named_rval_function
317
 
  : NAME LPAREN expressions RPAREN { result = Factory.CALL_NAMED(val[0][:value], true, val[2]) ; loc result, val[0], val[3] }
318
 
  | NAME LPAREN RPAREN             { result = Factory.CALL_NAMED(val[0][:value], true, []) ; loc result, val[0], val[2] }
319
 
 
320
 
quotedtext
321
 
  : STRING       { result = Factory.literal(val[0][:value]) ; loc result, val[0] }
322
 
  | dqpre dqrval { result = Factory.string(val[0], *val[1]) ; loc result, val[0], val[1][-1] } 
323
 
 
324
 
dqpre           : DQPRE      { result = Factory.literal(val[0][:value]); loc result, val[0] }
325
 
dqpost          : DQPOST     { result = Factory.literal(val[0][:value]); loc result, val[0] }
326
 
dqmid           : DQMID      { result = Factory.literal(val[0][:value]); loc result, val[0] }
327
 
text_expression : expression { result = Factory.TEXT(val[0]) }
328
 
 
329
 
dqrval
330
 
  : text_expression dqtail { result = [val[0]] + val[1] }
331
 
  
332
 
dqtail
333
 
  : dqpost       { result = [val[0]] }
334
 
  | dqmid dqrval  { result = [val[0]] + val[1] }
335
 
 
336
 
 
337
 
# Reference to Resource (future also reference to other instances of other types than Resources).
338
 
# First form (lower case name) is deprecated (deprecation message handled in validation). Note that
339
 
# this requires use of token NAME since a rule call to name causes shift reduce conflict with
340
 
# a function call NAME NAME (calling function with NAME as argument e.g. foo bar).
341
 
#
342
 
# Produces InstanceReference
343
 
resourceref
344
 
  : NAME LBRACK expressions RBRACK {
345
 
          # Would want to use rule name here, but can't (need a NAME with higher precedence), so must
346
 
          # create a QualifiedName instance here for NAME 
347
 
      result = Factory.INSTANCE(Factory.QNAME_OR_NUMBER(val[0][:value]), val[2]);
348
 
      loc result, val[0], val[2][-1]
349
 
    }
350
 
  | type LBRACK expressions RBRACK {
351
 
      result = Factory.INSTANCE(val[0], val[2]); 
352
 
      loc result, val[0], val[2][-1]
353
 
    }
354
 
 
355
 
# Changed from Puppet 3x where there is no else part on unless
356
 
#
357
 
unless_expression
358
 
  : UNLESS expression LBRACE statements RBRACE unless_else {
359
 
      @lexer.commentpop
360
 
      result = Factory.UNLESS(val[1], Factory.block_or_expression(*val[3]), val[5])
361
 
      loc result, val[0], val[4]
362
 
    }
363
 
  | UNLESS expression LBRACE RBRACE unless_else {
364
 
      @lexer.commentpop
365
 
      result = Factory.UNLESS(val[1], nil, nil)
366
 
      loc result, val[0], val[4]
367
 
    }
368
 
 
369
 
# Different from else part of if, since "elsif" is not supported, but else is
370
 
#
371
 
# Produces [Model::Expression, nil] - nil if there is no else or elsif part
372
 
unless_else
373
 
  : # nothing
374
 
  | ELSE LBRACE statements RBRACE {
375
 
      @lexer.commentpop
376
 
      result = Factory.block_or_expression(*val[2])
377
 
      loc result, val[0], val[3]
378
 
    }
379
 
  | ELSE LBRACE RBRACE {
380
 
      @lexer.commentpop
381
 
          result = nil # don't think a nop is needed here either
382
 
    }
383
 
 
384
 
# Produces Model::IfExpression
385
 
if_expression
386
 
  : IF if_expression_part {
387
 
      result = val[1]
388
 
    }
389
 
 
390
 
# Produces Model::IfExpression
391
 
if_expression_part
392
 
  : expression LBRACE statements RBRACE else {
393
 
      @lexer.commentpop
394
 
      result = Factory.IF(val[0], Factory.block_or_expression(*val[2]), val[4])
395
 
      loc(result, val[0], (val[4] ? val[4] : val[3]))
396
 
    }
397
 
  | expression LBRACE RBRACE else {
398
 
      result = Factory.IF(val[0], nil, val[3])
399
 
      loc(result, val[0], (val[3] ? val[3] : val[2]))
400
 
    }
401
 
 
402
 
# Produces [Model::Expression, nil] - nil if there is no else or elsif part
403
 
else
404
 
  : # nothing
405
 
  | ELSIF if_expression_part { result = val[1] }
406
 
  | ELSE LBRACE statements RBRACE {
407
 
      @lexer.commentpop
408
 
      result = Factory.block_or_expression(*val[2])
409
 
      loc result, val[0], val[3]
410
 
    }
411
 
  | ELSE LBRACE RBRACE {
412
 
      @lexer.commentpop
413
 
          result = nil # don't think a nop is needed here either
414
 
    }
415
 
 
416
 
# Produces Model::Expression
417
 
expression
418
 
  : rvalue
419
 
  | hash
420
 
  | expression IN expression           { result = val[0].in val[2]  ; loc result, val[1] }
421
 
  | expression MATCH match_rvalue      { result = val[0] =~  val[2] ; loc result, val[1] }
422
 
  | expression NOMATCH match_rvalue    { result = val[0].mne val[2] ; loc result, val[1] }
423
 
  | expression PLUS expression         { result = val[0] +   val[2] ; loc result, val[1] }
424
 
  | expression MINUS expression        { result = val[0] -   val[2] ; loc result, val[1] }
425
 
  | expression DIV expression          { result = val[0] /   val[2] ; loc result, val[1] }
426
 
  | expression TIMES expression        { result = val[0] *   val[2] ; loc result, val[1] }
427
 
  | expression LSHIFT expression       { result = val[0] <<  val[2] ; loc result, val[1] }
428
 
  | expression RSHIFT expression       { result = val[0] >>  val[2] ; loc result, val[1] }
429
 
  | MINUS expression =UMINUS           { result = val[1].minus()    ; loc result, val[0] }
430
 
  | expression NOTEQUAL expression     { result = val[0].ne  val[2] ; loc result, val[1] }
431
 
  | expression ISEQUAL expression      { result = val[0] ==  val[2] ; loc result, val[1] }
432
 
  | expression GREATERTHAN expression  { result = val[0] >   val[2] ; loc result, val[1] }
433
 
  | expression GREATEREQUAL expression { result = val[0] >=  val[2] ; loc result, val[1] }
434
 
  | expression LESSTHAN expression     { result = val[0] <   val[2] ; loc result, val[1] }
435
 
  | expression LESSEQUAL expression    { result = val[0] <=  val[2] ; loc result, val[1] }
436
 
  | NOT expression                     { result = val[1].not        ; loc result, val[0] }
437
 
  | expression AND expression          { result = val[0].and val[2] ; loc result, val[1] }
438
 
  | expression OR expression           { result = val[0].or  val[2] ; loc result, val[1] }
439
 
  | LPAREN expression RPAREN           { result = val[1]            ;                    }
440
 
  | call_method_with_lambda 
441
 
 
442
 
match_rvalue
443
 
  : regex
444
 
  | quotedtext
445
 
  
446
 
# Produces Model::CaseExpression
447
 
casestatement
448
 
  : CASE expression LBRACE case_options RBRACE {
449
 
      @lexer.commentpop
450
 
      result = Factory.CASE(val[1], *val[3])
451
 
      loc result, val[0], val[4]
452
 
    }
453
 
 
454
 
# Produces Array<Model::CaseOption>
455
 
case_options
456
 
  : case_option               { result = [val[0]] }
457
 
  | case_options case_option { result = val[0].push val[1] }
458
 
 
459
 
# Produced Model::CaseOption (aka When)
460
 
case_option
461
 
  : case_values COLON LBRACE statements RBRACE {
462
 
      @lexer.commentpop
463
 
      result = Factory.WHEN(val[0], val[3])
464
 
      loc result, val[1], val[4]
465
 
    }
466
 
  | case_values COLON LBRACE RBRACE {
467
 
      @lexer.commentpop
468
 
      result = Factory.WHEN(val[0], nil)
469
 
      loc result, val[1], val[3]
470
 
    }
471
 
 
472
 
# Produces Array<Expression> mostly literals
473
 
case_values
474
 
  : selectable                   { result = [val[0]] }
475
 
  | case_values COMMA selectable { result = val[0].push val[2] }
476
 
 
477
 
# Produces Model::SelectorExpression
478
 
selector
479
 
  : selectable QMARK selector_entries { result = val[0].select(*val[2]) ; loc result, val[1] }
480
 
 
481
 
# Produces Array<Model::SelectorEntry>
482
 
selector_entries
483
 
  : selector_entry { result = [val[0]] }
484
 
  | LBRACE selector_entry_list endcomma RBRACE {
485
 
      @lexer.commentpop
486
 
      result = val[1]
487
 
    }
488
 
 
489
 
# Produces Array<Model::SelectorEntry>
490
 
selector_entry_list
491
 
  : selector_entry                           { result = [val[0]] }
492
 
  | selector_entry_list COMMA selector_entry { result = val[0].push val[2] }
493
 
 
494
 
# Produces a Model::SelectorEntry
495
 
selector_entry
496
 
  : selectable FARROW rvalue { result = Factory.MAP(val[0], val[2]) ; loc result, val[1] }
497
 
 
498
 
# Produces Model::Expression (most of the literals)
499
 
selectable
500
 
  : name
501
 
  | type
502
 
  | quotedtext
503
 
  | variable
504
 
  | call_named_rval_function
505
 
  | boolean
506
 
  | undef
507
 
  | hasharrayaccess
508
 
  | default
509
 
  | regex
510
 
 
511
 
  
512
 
 
513
 
# Produces nil (noop)
514
 
import
515
 
  : IMPORT strings {
516
 
      error "Import not supported in this version of the parser", \
517
 
          :line => stmt.context[:line], :file => stmt.context[:file]
518
 
      result = nil
519
 
  }
520
 
 
521
 
# IMPORT (T.B DEPRECATED IN PUPPET WHEN IT HAS BEEN FIGURED OUT HOW TO SUPPORT
522
 
# THE THINGS IMPORTS ARE USED FOR.
523
 
# BOLDLY DECIDED TO SKIP THIS COMPLETELY IN THIS IMPLEMENTATION - will trigger an error
524
 
#
525
 
# These are only used for importing, no interpolation
526
 
string
527
 
  : STRING       { result = [val[0][:value]] }
528
 
 
529
 
strings
530
 
  :  string
531
 
  |  strings COMMA string { result = val[0].push val[2] }
532
 
 
533
 
# Produces Model::Definition
534
 
definition
535
 
  : DEFINE classname parameter_list LBRACE statements RBRACE {
536
 
      @lexer.commentpop
537
 
      result = Factory.DEFINITION(classname(val[1][:value]), val[2], val[4])
538
 
      loc result, val[0], val[5]
539
 
      @lexer.indefine = false
540
 
    }
541
 
  | DEFINE classname parameter_list LBRACE RBRACE {
542
 
      @lexer.commentpop
543
 
      result = Factory.DEFINITION(classname(val[1][:value]), val[2], nil)
544
 
      loc result, val[0], val[4]
545
 
      @lexer.indefine = false
546
 
    }
547
 
 
548
 
# ORIGINAL COMMENT: Our class gets defined in the parent namespace, not our own. 
549
 
#    WAT ??! This is way odd; should get its complete name, classnames do not nest
550
 
#    Seems like the call to classname makes use of the name scope
551
 
#    (This is uneccesary, since the parent name is known when evaluating)
552
 
#
553
 
# Produces Model::HostClassDefinition
554
 
#
555
 
hostclass
556
 
  : CLASS classname parameter_list classparent LBRACE statements RBRACE {
557
 
      @lexer.commentpop
558
 
      @lexer.namepop
559
 
      result = Factory.HOSTCLASS(classname(val[1][:value]), val[2], token_text(val[3]), val[5])
560
 
      loc result, val[0], val[6]
561
 
    }
562
 
  | CLASS classname parameter_list classparent LBRACE RBRACE {
563
 
      @lexer.commentpop
564
 
      @lexer.namepop
565
 
      result = Factory.HOSTCLASS(classname(val[1][:value]), val[2], token_text(val[3]), nil)
566
 
      loc result, val[0], val[5]
567
 
      }
568
 
 
569
 
# Produces Model::NodeDefinition
570
 
nodedef
571
 
  : NODE hostnames nodeparent LBRACE statements RBRACE {
572
 
      @lexer.commentpop
573
 
      result = Factory.NODE(val[1], val[2], val[4])
574
 
      loc result, val[0], val[5]
575
 
    }
576
 
  | NODE hostnames nodeparent LBRACE RBRACE {
577
 
      @lexer.commentpop
578
 
      result = Factory.NODE(val[1], val[2], nil)
579
 
      loc result, val[0], val[4]
580
 
    }
581
 
 
582
 
# String result
583
 
classname
584
 
  : NAME  { result = val[0] }
585
 
  | CLASS { result = val[0] }
586
 
 
587
 
# Hostnames is not a list of names, it is a list of name matchers (including a Regexp).
588
 
# (The old implementation had a special "Hostname" object with some minimal validation)
589
 
#
590
 
# Produces Array<Model::LiteralExpression> 
591
 
#
592
 
hostnames
593
 
  : nodename                 { result = [result] }
594
 
  | hostnames COMMA nodename { result = val[0].push(val[2]) }
595
 
 
596
 
# Produces Model::LiteralExpression
597
 
#
598
 
nodename
599
 
  : hostname
600
 
 
601
 
# Produces a LiteralExpression (string, :default, or regexp)
602
 
hostname
603
 
  : NAME    { result = Factory.fqn(val[0][:value]); loc result, val[0] }
604
 
  | STRING  { result = Factory.literal(val[0][:value]); loc result, val[0] }
605
 
  | DEFAULT { result = Factory.literal(:default); loc result, val[0] }
606
 
  | regex
607
 
 
608
 
 
609
 
# Produces Array<Model::Parameter>
610
 
parameter_list
611
 
  : nil                               { result = [] }
612
 
  | LPAREN  RPAREN                    { result = [] }
613
 
  | LPAREN parameters endcomma RPAREN { result = val[1] }
614
 
 
615
 
# Produces Array<Model::Parameter>
616
 
parameters
617
 
  : parameter                 { result = [val[0]] }
618
 
  | parameters COMMA parameter { result = val[0].push(val[2]) }
619
 
 
620
 
# Produces Model::Parameter
621
 
parameter
622
 
  : VARIABLE EQUALS expression { result = Factory.PARAM(val[0][:value], val[2]) ; loc result, val[0] }
623
 
  | VARIABLE                   { result = Factory.PARAM(val[0][:value]); loc result, val[0] }
624
 
 
625
 
# Produces Expression, since hostname is an Expression
626
 
nodeparent
627
 
  : nil
628
 
  | INHERITS hostname { result = val[1] }
629
 
 
630
 
# Produces String, name or nil result
631
 
classparent
632
 
  : nil
633
 
  | INHERITS classnameordefault { result = val[1] }
634
 
 
635
 
# Produces String (this construct allows a class to be named "default" and to be referenced as
636
 
# the parent class.
637
 
# TODO: Investigate the validity 
638
 
# Produces a String (classname), or a token (DEFAULT).
639
 
#
640
 
classnameordefault
641
 
  : classname
642
 
  | DEFAULT
643
 
 
644
 
rvalue
645
 
  : quotedtext
646
 
  | name
647
 
  | type
648
 
  | boolean
649
 
  | selector
650
 
  | variable
651
 
  | array
652
 
  | hasharrayaccesses
653
 
  | resourceref
654
 
  | call_named_rval_function
655
 
  | undef
656
 
 
657
 
array
658
 
  : LBRACK expressions       RBRACK { result = Factory.LIST(val[1]); loc result, val[0], val[2] }
659
 
  | LBRACK expressions COMMA RBRACK { result = Factory.LIST(val[1]); loc result, val[0], val[3] }
660
 
  | LBRACK                   RBRACK { result = Factory.literal([]) ; loc result, val[0] }
661
 
 
662
 
 
663
 
hash
664
 
  : LBRACE hashpairs RBRACE       { result = Factory.HASH(val[1]); loc result, val[0], val[2] }
665
 
  | LBRACE hashpairs COMMA RBRACE { result = Factory.HASH(val[1]); loc result, val[0], val[3] }
666
 
  | LBRACE RBRACE                 { result = Factory.literal({}) ; loc result, val[0], val[3] }
667
 
 
668
 
hashpairs
669
 
  : hashpair                 { result = [val[0]] }
670
 
  | hashpairs COMMA hashpair { result = val[0].push val[2] } 
671
 
 
672
 
hashpair
673
 
  : key FARROW expression { result = Factory.KEY_ENTRY(val[0], val[2]); loc result, val[1] }
674
 
 
675
 
key
676
 
  : NAME       { result = Factory.literal(val[0][:value]) ; loc result, val[0] }
677
 
  | quotedtext { result = val[0] }
678
 
 
679
 
# NOTE: Limitation that LHS is a variable, means that it is not possible to do foo(10)[2] without
680
 
# using an intermediate variable
681
 
#
682
 
hasharrayaccess
683
 
  : variable LBRACK expression RBRACK { result = val[0][val[2]]; loc result, val[0], val[3] }
684
 
 
685
 
hasharrayaccesses
686
 
  : hasharrayaccess
687
 
  | hasharrayaccesses LBRACK expression RBRACK { result = val[0][val[2]] ; loc result, val[1], val[3] }
688
 
 
689
 
# Produces Model::VariableExpression
690
 
variable : VARIABLE { result = Factory.fqn(val[0][:value]).var ; loc result, val[0] }
691
 
undef    : UNDEF    { result = Factory.literal(:undef); loc result, val[0] }
692
 
name     : NAME     { result = Factory.QNAME_OR_NUMBER(val[0][:value]) ; loc result, val[0] }
693
 
type     : CLASSREF { result = Factory.QREF(val[0][:value])  ; loc result, val[0] }
694
 
 
695
 
default
696
 
  : DEFAULT { result = Factory.literal(:default); loc result, val[0] }
697
 
 
698
 
boolean
699
 
  # Assumes lexer produces a Boolean value for booleans, or this will go wrong (e.g. produce. LiteralString)
700
 
  : BOOLEAN { result = Factory.literal(val[0][:value]) ; loc result, val[0] }
701
 
 
702
 
regex
703
 
  : REGEX { result = Factory.literal(val[0][:value]); loc result, val[0] }
704
 
 
705
 
# ---Special markers & syntactic sugar
706
 
 
707
 
# WAT !!!! this means array can be [1=>2=>3], func (1=>2=>3), and other retarded constructs
708
 
# TODO: Remove the FARROW (investigate if there is any validity)
709
 
comma
710
 
  : FARROW
711
 
  | COMMA
712
 
 
713
 
endcomma
714
 
  : #
715
 
  | COMMA { result = nil }
716
 
 
717
 
endsemi
718
 
  : #
719
 
  | SEMIC
720
 
 
721
 
nil
722
 
  : { result = nil}
723
 
 
724
 
## Empty list - not really needed? TODO: Check if this can be removed
725
 
#empty_list
726
 
#  : { result = [] }
727
 
 
728
 
end
729
 
 
730
 
---- header ----
731
 
require 'puppet'
732
 
require 'puppet/util/loadedfile'
733
 
require 'puppet/pops'
734
 
 
735
 
module Puppet
736
 
  class ParseError < Puppet::Error; end
737
 
  class ImportError < Racc::ParseError; end
738
 
  class AlreadyImportedError < ImportError; end
739
 
end
740
 
 
741
 
---- inner ----
742
 
 
743
 
# Make emacs happy
744
 
# Local Variables:
745
 
# mode: ruby
746
 
# End: