mof 0.3.0 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,661 @@
1
+ /*
2
+ * According to appendix A of
3
+ * http://www.dmtf.org/standards/cim/cim_spec_v22
4
+ */
5
+
6
+ class MOF::Parser
7
+ prechigh
8
+ /* nonassoc UMINUS */
9
+ left '*' '/'
10
+ left '+' '-'
11
+ preclow
12
+
13
+ token PRAGMA INCLUDE IDENTIFIER CLASS ASSOCIATION INDICATION
14
+ AMENDED ENABLEOVERRIDE DISABLEOVERRIDE RESTRICTED TOSUBCLASS TOINSTANCE
15
+ TRANSLATABLE QUALIFIER SCOPE SCHEMA PROPERTY REFERENCE
16
+ METHOD PARAMETER FLAVOR INSTANCE
17
+ AS REF ANY OF
18
+ DT_VOID
19
+ DT_UINT8 DT_SINT8 DT_UINT16 DT_SINT16 DT_UINT32 DT_SINT32
20
+ DT_UINT64 DT_SINT64 DT_REAL32 DT_REAL64 DT_CHAR16 DT_STR
21
+ DT_BOOL DT_DATETIME
22
+ positiveDecimalValue
23
+ stringValue
24
+ realValue
25
+ charValue
26
+ booleanValue
27
+ nullValue
28
+ binaryValue
29
+ octalValue
30
+ decimalValue
31
+ hexValue
32
+
33
+ rule
34
+
35
+ /* Returns a Hash of filename and MofResult */
36
+ mofSpecification
37
+ : /* empty */
38
+ { result = Hash.new }
39
+ | mofProduction
40
+ { result = { @name => @result } }
41
+ | mofSpecification mofProduction
42
+ { result = val[0]
43
+ result[@name] = @result
44
+ }
45
+ ;
46
+
47
+ mofProduction
48
+ : compilerDirective
49
+ | classDeclaration
50
+ { #puts "Class '#{val[0].name}'"
51
+ @result.classes << val[0]
52
+ }
53
+ | qualifierDeclaration
54
+ { @result.qualifiers << val[0]
55
+ @qualifiers[val[0].name.downcase] = val[0]
56
+ }
57
+ | instanceDeclaration
58
+ { @result.instances << val[0] }
59
+ ;
60
+
61
+ /***
62
+ * compilerDirective
63
+ *
64
+ */
65
+
66
+ compilerDirective
67
+ : "#" PRAGMA INCLUDE pragmaParameters_opt
68
+ { raise MOF::Helper::Error.new(@name,@lineno,@line,"Missing filename after '#pragma include'") unless val[3]
69
+ open val[3], :pragma
70
+ }
71
+ | "#" PRAGMA pragmaName pragmaParameters_opt
72
+ | "#" INCLUDE pragmaParameters_opt
73
+ { raise StyleError.new(@name,@lineno,@line,"Use '#pragma include' instead of '#include'") unless @style == :wmi
74
+ raise MOF::Helper::Error.new(@name,@lineno,@line,"Missing filename after '#include'") unless val[2]
75
+ open val[2], :pragma
76
+ }
77
+ ;
78
+
79
+ pragmaName
80
+ : IDENTIFIER
81
+ ;
82
+
83
+ pragmaParameters_opt
84
+ : /* empty */
85
+ { raise StyleError.new(@name,@lineno,@line,"#pragma parameter missing") unless @style == :wmi }
86
+ | "(" pragmaParameterValues ")"
87
+ { result = val[1] }
88
+ ;
89
+
90
+ pragmaParameterValues
91
+ : pragmaParameterValue
92
+ | pragmaParameterValues "," pragmaParameterValue
93
+ ;
94
+
95
+ pragmaParameterValue
96
+ : string
97
+ | integerValue
98
+ { raise StyleError.new(@name,@lineno,@line,"#pragma parameter missing") unless @style == :wmi }
99
+ | IDENTIFIER
100
+ ;
101
+
102
+ /***
103
+ * classDeclaration
104
+ *
105
+ */
106
+
107
+ classDeclaration
108
+ : qualifierList_opt CLASS className alias_opt superClass_opt "{" classFeatures "}" ";"
109
+ { qualifiers = val[0]
110
+ features = val[6]
111
+ if qualifiers and qualifiers.include?(:association, :bool)
112
+ # FIXME: 'association' must be first
113
+ # Context:
114
+ #
115
+ # The remaining qualifier list must not include
116
+ # the ASSOCIATION qualifier again. If the
117
+ # association has no super association, then at
118
+ # least two references must be specified! The
119
+ # ASSOCIATION qualifier may be omitted in
120
+ # sub associations.
121
+ result = CIM::Association.new(val[2],qualifiers,val[3],val[4],features)
122
+ elsif qualifiers and qualifiers.include?(:indication, :bool)
123
+ # FIXME: 'indication' must be first
124
+ # FIXME: features must not include references
125
+ result = CIM::Indication.new(val[2],qualifiers,val[3],val[4],features)
126
+ else
127
+ # FIXME: features must not include references
128
+ result = CIM::Class.new(val[2],qualifiers,val[3],val[4],features)
129
+ end
130
+ }
131
+ ;
132
+
133
+ classFeatures
134
+ : /* empty */
135
+ { result = [] }
136
+ | classFeatures classFeature
137
+ { result = val[0] << val[1] }
138
+ ;
139
+
140
+ classFeature
141
+ : propertyDeclaration
142
+ | methodDeclaration
143
+ | referenceDeclaration /* must have association qualifier */
144
+ ;
145
+
146
+
147
+ qualifierList_opt
148
+ : /* empty */
149
+ | qualifierList
150
+ { result = CIM::QualifierSet.new val[0] }
151
+ ;
152
+
153
+ qualifierList
154
+ : "[" qualifier qualifiers "]"
155
+ { result = val[2]
156
+ result.unshift val[1] if val[1] }
157
+ ;
158
+
159
+ qualifiers
160
+ : /* empty */
161
+ { result = [] }
162
+ | qualifiers "," qualifier
163
+ { result = val[0]
164
+ result << val[2] if val[2]
165
+ }
166
+ ;
167
+
168
+ qualifier
169
+ : qualifierName qualifierParameter_opt flavor_opt
170
+ { # Get qualifier decl
171
+ qualifier = case val[0]
172
+ when CIM::Qualifier: val[0].definition
173
+ when CIM::QualifierDeclaration: val[0]
174
+ when String: @qualifiers[val[0].downcase]
175
+ else
176
+ nil
177
+ end
178
+ raise MOF::Helper::Error.new(@name,@lineno,@line,"'#{val[0]}' is not a valid qualifier") unless qualifier
179
+ value = val[1]
180
+ raise MOF::Helper::Error.new(@name,@lineno,@line,"#{value.inspect} does not match qualifier type '#{qualifier.type}'") unless qualifier.type.matches?(value)||@style == :wmi
181
+ # Don't propagate a boolean 'false'
182
+ if qualifier.type == :bool && value == false
183
+ result = nil
184
+ else
185
+ result = CIM::Qualifier.new(qualifier,value,val[2])
186
+ end
187
+ }
188
+ ;
189
+
190
+ flavor_opt
191
+ : /* empty */
192
+ | ":" flavor
193
+ { result = CIM::QualifierFlavors.new val[1] }
194
+ ;
195
+
196
+ qualifierParameter_opt
197
+ : /* empty */
198
+ | qualifierParameter
199
+ ;
200
+
201
+ qualifierParameter
202
+ : "(" constantValue ")"
203
+ { result = val[1] }
204
+ | arrayInitializer
205
+ ;
206
+
207
+ /* CIM::Flavors */
208
+ flavor
209
+ : AMENDED | ENABLEOVERRIDE | DISABLEOVERRIDE | RESTRICTED | TOSUBCLASS | TRANSLATABLE | TOINSTANCE
210
+ { case val[0].to_sym
211
+ when :amended, :toinstance
212
+ raise StyleError.new(@name,@lineno,@line,"'#{val[0]}' is not a valid flavor") unless @style == :wmi
213
+ end
214
+ }
215
+ ;
216
+
217
+ alias_opt
218
+ : /* empty */
219
+ | alias
220
+ ;
221
+
222
+ superClass_opt
223
+ : /* empty */
224
+ | superClass
225
+ ;
226
+
227
+ className
228
+ : IDENTIFIER /* must be <schema>_<classname> in CIM v2.x */
229
+ { raise ParseError.new("Class name must be prefixed by '<schema>_'") unless val[0].include?("_") || @style == :wmi }
230
+ ;
231
+
232
+ alias
233
+ : AS aliasIdentifier
234
+ { result = val[1] }
235
+ ;
236
+
237
+ aliasIdentifier
238
+ : "$" IDENTIFIER /* NO whitespace ! */
239
+ { result = val[1] }
240
+ ;
241
+
242
+ superClass
243
+ : ":" className
244
+ { result = val[1] }
245
+ ;
246
+
247
+
248
+ propertyDeclaration
249
+ : qualifierList_opt dataType propertyName array_opt defaultValue_opt ";"
250
+ { if val[3]
251
+ type = CIM::Array.new val[3],val[1]
252
+ else
253
+ type = val[1]
254
+ end
255
+ result = CIM::Property.new(type,val[2],val[0],val[4])
256
+ }
257
+ ;
258
+
259
+ referenceDeclaration
260
+ : qualifierList_opt objectRef referenceName array_opt defaultValue_opt ";"
261
+ { if val[4]
262
+ raise StyleError.new(@name,@lineno,@line,"Array not allowed in reference declaration") unless @style == :wmi
263
+ end
264
+ result = CIM::Reference.new(val[1],val[2],val[0],val[4]) }
265
+ ;
266
+
267
+ methodDeclaration
268
+ : qualifierList_opt dataType methodName "(" parameterList_opt ")" ";"
269
+ { result = CIM::Method.new(val[1],val[2],val[0],val[4]) }
270
+ ;
271
+
272
+ propertyName
273
+ : IDENTIFIER
274
+ | PROPERTY
275
+ { # tmplprov.mof has 'string Property;'
276
+ raise StyleError.new(@name,@lineno,@line,"Invalid keyword '#{val[0]}' used for property name") unless @style == :wmi
277
+ }
278
+ ;
279
+
280
+ referenceName
281
+ : IDENTIFIER
282
+ | INDICATION
283
+ { result = "Indication" }
284
+ ;
285
+
286
+ methodName
287
+ : IDENTIFIER
288
+ ;
289
+
290
+ dataType
291
+ : DT_UINT8
292
+ | DT_SINT8
293
+ | DT_UINT16
294
+ | DT_SINT16
295
+ | DT_UINT32
296
+ | DT_SINT32
297
+ | DT_UINT64
298
+ | DT_SINT64
299
+ | DT_REAL32
300
+ | DT_REAL64
301
+ | DT_CHAR16
302
+ | DT_STR
303
+ | DT_BOOL
304
+ | DT_DATETIME
305
+ | DT_VOID
306
+ { raise StyleError.new(@name,@lineno,@line,"'void' is not a valid datatype") unless @style == :wmi }
307
+ ;
308
+
309
+ objectRef
310
+ : className
311
+ { # WMI uses class names as data types (without REF ?!)
312
+ raise StyleError.new(@name,@lineno,@line,"Expected 'ref' keyword after classname '#{val[0]}'") unless @style == :wmi
313
+ result = CIM::ReferenceType.new val[0]
314
+ }
315
+
316
+ | className REF
317
+ { result = CIM::ReferenceType.new val[0] }
318
+ ;
319
+
320
+ parameterList_opt
321
+ : /* empty */
322
+ | parameterList
323
+ ;
324
+
325
+ parameterList
326
+ : parameter parameters
327
+ { result = val[1].unshift val[0] }
328
+ ;
329
+
330
+ parameters
331
+ : /* empty */
332
+ { result = [] }
333
+ | parameters "," parameter
334
+ { result = val[0] << val[2] }
335
+ ;
336
+
337
+ parameter
338
+ : qualifierList_opt typespec parameterName array_opt parameterValue_opt
339
+ { if val[3]
340
+ type = CIM::Array.new val[3], val[1]
341
+ else
342
+ type = val[1]
343
+ end
344
+ result = CIM::Property.new(type,val[2],val[0])
345
+ }
346
+ ;
347
+
348
+ typespec
349
+ : dataType
350
+ | objectRef
351
+ ;
352
+
353
+ parameterName
354
+ : IDENTIFIER
355
+ ;
356
+
357
+ array_opt
358
+ : /* empty */
359
+ | array
360
+ ;
361
+
362
+ parameterValue_opt
363
+ : /* empty */
364
+ | defaultValue
365
+ { raise "Default parameter value not allowed in syntax style '{@style}'" unless @style == :wmi }
366
+ ;
367
+
368
+ array
369
+ : "[" positiveDecimalValue_opt "]"
370
+ { result = val[1] }
371
+ ;
372
+
373
+ positiveDecimalValue_opt
374
+ : /* empty */
375
+ { result = -1 }
376
+ | positiveDecimalValue
377
+ ;
378
+
379
+ defaultValue_opt
380
+ : /* empty */
381
+ | defaultValue
382
+ ;
383
+
384
+ defaultValue
385
+ : "=" initializer
386
+ { result = val[1] }
387
+ ;
388
+
389
+ initializer
390
+ : constantValue
391
+ | arrayInitializer
392
+ | referenceInitializer
393
+ ;
394
+
395
+ arrayInitializer
396
+ : "{" constantValues "}"
397
+ { result = val[1] }
398
+ ;
399
+
400
+ constantValues
401
+ : /* empty */
402
+ | constantValue
403
+ { result = [ val[0] ] }
404
+ | constantValues "," constantValue
405
+ { result = val[0] << val[2] }
406
+ ;
407
+
408
+ constantValue
409
+ : integerValue
410
+ | realValue
411
+ | charValue
412
+ | string
413
+ | booleanValue
414
+ | nullValue
415
+ | instance
416
+ { raise "Instance as property value not allowed in syntax style '{@style}'" unless @style == :wmi }
417
+ ;
418
+
419
+ integerValue
420
+ : binaryValue
421
+ | octalValue
422
+ | decimalValue
423
+ | positiveDecimalValue
424
+ | hexValue
425
+ ;
426
+
427
+ string
428
+ : stringValue
429
+ | string stringValue
430
+ { result = val[0] + val[1] }
431
+ ;
432
+
433
+ referenceInitializer
434
+ : objectHandle
435
+ | aliasIdentifier
436
+ ;
437
+
438
+ objectHandle
439
+ : namespace_opt modelPath
440
+ ;
441
+
442
+ namespace_opt
443
+ : /* empty */
444
+ | namespaceHandle ":"
445
+ ;
446
+
447
+ namespaceHandle
448
+ : IDENTIFIER
449
+ ;
450
+
451
+ /*
452
+ * Note
453
+ : structure depends on type of namespace
454
+ */
455
+
456
+ modelPath
457
+ : className "." keyValuePairList
458
+ ;
459
+
460
+ keyValuePairList
461
+ : keyValuePair keyValuePairs
462
+ ;
463
+
464
+ keyValuePairs
465
+ : /* empty */
466
+ | keyValuePairs "," keyValuePair
467
+ ;
468
+
469
+ keyValuePair
470
+ : keyname "=" initializer
471
+ ;
472
+
473
+ keyname
474
+ : propertyName | referenceName
475
+ ;
476
+
477
+ /***
478
+ * qualifierDeclaration
479
+ *
480
+ */
481
+
482
+ qualifierDeclaration
483
+ /* 0 1 2 3 4 */
484
+ : QUALIFIER qualifierName qualifierType scope defaultFlavor_opt ";"
485
+ { result = CIM::QualifierDeclaration.new( val[1], val[2][0], val[2][1], val[3], val[4]) }
486
+ ;
487
+
488
+ defaultFlavor_opt
489
+ : /* empty */
490
+ | defaultFlavor
491
+ ;
492
+
493
+ qualifierName
494
+ : IDENTIFIER
495
+ | ASSOCIATION /* meta qualifier */
496
+ | INDICATION /* meta qualifier */
497
+ | SCHEMA
498
+ ;
499
+
500
+ /* [type, value] */
501
+ qualifierType
502
+ : ":" dataType array_opt defaultValue_opt
503
+ { type = val[2].nil? ? val[1] : CIM::Array.new(val[2],val[1])
504
+ result = [ type, val[3] ]
505
+ }
506
+ ;
507
+
508
+ scope
509
+ : "," SCOPE "(" metaElements ")"
510
+ { result = CIM::QualifierScopes.new(val[3]) }
511
+ ;
512
+
513
+ metaElements
514
+ : metaElement
515
+ { result = [ val[0] ] }
516
+ | metaElements "," metaElement
517
+ { result = val[0] << val[2] }
518
+ ;
519
+
520
+ metaElement
521
+ : SCHEMA
522
+ | CLASS
523
+ | ASSOCIATION
524
+ | INDICATION
525
+ | QUALIFIER
526
+ | PROPERTY
527
+ | REFERENCE
528
+ | METHOD
529
+ | PARAMETER
530
+ | ANY
531
+ ;
532
+
533
+ defaultFlavor
534
+ : "," FLAVOR "(" flavors ")"
535
+ { result = CIM::QualifierFlavors.new val[3] }
536
+ ;
537
+
538
+ flavors
539
+ : flavor
540
+ { result = [ val[0] ] }
541
+ | flavors "," flavor
542
+ { result = val[0] << val[2] }
543
+ ;
544
+
545
+ /***
546
+ * instanceDeclaration
547
+ *
548
+ */
549
+
550
+ instanceDeclaration
551
+ : instance ";"
552
+ ;
553
+
554
+ instance
555
+ : qualifierList_opt INSTANCE OF className alias_opt "{" valueInitializers "}"
556
+ ;
557
+
558
+ valueInitializers
559
+ : valueInitializer
560
+ | valueInitializers valueInitializer
561
+ ;
562
+
563
+ valueInitializer
564
+ : qualifierList_opt keyname "=" initializer ";"
565
+ | qualifierList_opt keyname ";"
566
+ { raise "Instance property '#{val[1]} must have a value" unless @style == :wmi }
567
+ ;
568
+
569
+ end # class Parser
570
+
571
+ ---- header ----
572
+
573
+ # parser.rb - generated by racc
574
+
575
+ require 'strscan'
576
+ require 'rubygems'
577
+ require 'cim'
578
+ require File.join(File.dirname(__FILE__), 'result')
579
+ require File.join(File.dirname(__FILE__), 'scanner')
580
+ require File.join(File.dirname(__FILE__), 'helper')
581
+
582
+ ---- inner ----
583
+
584
+ #
585
+ # Initialize MOF::Parser
586
+ # MOF::Parser.new options = {}
587
+ #
588
+ # options -> Hash of options
589
+ # :debug -> bool
590
+ # :includes -> array of include dirs
591
+ # :style -> :cim or :wmi
592
+ #
593
+ def initialize options = {}
594
+ @yydebug = options[:debug]
595
+ @includes = options[:includes] || []
596
+ @quiet = options[:quiet]
597
+ @style = options[:style] || :cim # default to style CIM v2.2 syntax
598
+
599
+ @lineno = 1
600
+ @file = nil
601
+ @iconv = nil
602
+ @eol = "\n"
603
+ @fname = nil
604
+ @fstack = []
605
+ @in_comment = false
606
+ @seen_files = []
607
+ @qualifiers = {}
608
+ end
609
+
610
+ #
611
+ # Make options hash from argv
612
+ #
613
+ # returns [ files, options ]
614
+ #
615
+
616
+ def self.argv_handler name, argv
617
+ files = []
618
+ options = { :namespace => "" }
619
+ while argv.size > 0
620
+ case opt = argv.shift
621
+ when "-h":
622
+ $stderr.puts "Ruby MOF compiler"
623
+ $stderr.puts "#{name} [-h] [-d] [-I <dir>] [<moffiles>]"
624
+ $stderr.puts "Compiles <moffile>"
625
+ $stderr.puts "\t-d debug"
626
+ $stderr.puts "\t-h this help"
627
+ $stderr.puts "\t-I <dir> include dir"
628
+ $stderr.puts "\t-f force"
629
+ $stderr.puts "\t-n <namespace>"
630
+ $stderr.puts "\t-o <output>"
631
+ $stderr.puts "\t-s <style> syntax style (wmi,cim)"
632
+ $stderr.puts "\t-q quiet"
633
+ $stderr.puts "\t<moffiles> file(s) to read (else use $stdin)"
634
+ exit 0
635
+ when "-f": options[:force] = true
636
+ when "-s": options[:style] = argv.shift.to_sym
637
+ when "-d": options[:debug] = true
638
+ when "-q": options[:quiet] = true
639
+ when "-I"
640
+ options[:includes] ||= []
641
+ dirname = argv.shift
642
+ unless File.directory?(dirname)
643
+ files << dirname
644
+ dirname = File.dirname(dirname)
645
+ end
646
+ options[:includes] << Pathname.new(dirname)
647
+ when "-n": options[:namespace] = argv.shift
648
+ when "-o": options[:output] = argv.shift
649
+ when /^-.+/:
650
+ $stderr.puts "Undefined option #{opt}"
651
+ else
652
+ files << opt
653
+ end
654
+ end
655
+ [ files, options ]
656
+ end
657
+
658
+ include Helper
659
+ include Scanner
660
+
661
+ ---- footer ----