File Coverage

blib/lib/MarpaX/Languages/IDL/AST.pm
Criterion Covered Total %
statement 34 36 94.4
branch n/a
condition n/a
subroutine 12 12 100.0
pod n/a
total 46 48 95.8


line stmt bran cond sub pod time code
1 1     1   103080 use strict;
  1         3  
  1         56  
2 1     1   6 use warnings FATAL => 'all';
  1         4  
  1         76  
3              
4             package MarpaX::Languages::IDL::AST;
5 1     1   503 use MarpaX::Languages::IDL::AST::Value;
  1         2  
  1         39  
6 1     1   522 use MarpaX::Languages::IDL::AST::Util;
  1         3  
  1         41  
7 1     1   7 use Scalar::Util qw/blessed reftype refaddr/;
  1         1  
  1         70  
8 1     1   875 use Data::Dumper;
  1         9547  
  1         101  
9 1     1   759 use Template;
  1         24860  
  1         55  
10 1     1   11 use Template::Constants qw/:chomp :debug/;
  1         2  
  1         333  
11 1     1   871 use File::ShareDir::ProjectDistDir 1.0 ':all', strict => 1;
  1         19726  
  1         7  
12 1     1   603 use Config;
  1         3  
  1         71  
13              
14             # ABSTRACT: Translate an IDL source to an AST
15              
16             our $VERSION = '0.005'; # VERSION
17              
18              
19 1     1   5 use Carp qw/carp croak/;
  1         2  
  1         89  
20 1     1   392 use Marpa::R2 qw//;
  0            
  0            
21             use File::Basename qw/basename fileparse/;
22             use File::Spec::Functions qw/case_tolerant rel2abs/;
23             use File::Slurp qw/read_file/;
24              
25             our $BLESS_PACKAGE = 'IDL::AST';
26             our $DATA = do {local $/; <DATA>};
27             our $G = Marpa::R2::Scanless::G->new({source => \$DATA, bless_package => $BLESS_PACKAGE});
28             # Marpa follows Unicode recommendation, i.e. perl's \R, that cannot be in a character class
29             our $NEWLINE_REGEXP = qr/(?>\x0D\x0A|\v)/;
30              
31              
32             sub new {
33             my ($class) = @_;
34              
35             my $self = {
36             };
37              
38             bless($self, $class);
39              
40             return $self;
41             }
42              
43              
44             sub parse {
45             my ($self, $path, $hashOptPtr) = @_;
46             #
47             # Parameters check
48             #
49             $hashOptPtr //= {};
50             if (ref($hashOptPtr) ne 'HASH') {
51             croak '3rd argument must be a pointer to HASH containing any Marpa::R2::Scanles::R option, except the grammar option';
52             }
53             foreach (qw/grammar semantics_package/) {
54             if (exists($hashOptPtr->{$_})) {
55             delete($hashOptPtr->{$_});
56             }
57             }
58             #
59             # IDL wants the filename to end with .idl
60             #
61             my ($filename, $directories, $suffix) = fileparse($path, qr/\.[^.]*/);
62             if (( case_tolerant() && (lc($suffix) ne '.idl')) ||
63             (! case_tolerant() && ( $suffix ne '.idl'))) {
64             carp "$path does not end with .idl";
65             }
66             #
67             # Load data
68             #
69             my $data = read_file($path);
70             #
71             # Regonizer
72             #
73             my $recce = Marpa::R2::Scanless::R->new({grammar => $G,
74             # trace_terminals => 1,
75             semantics_package => 'MarpaX::Languages::IDL::AST::Value',
76             %{$hashOptPtr}});
77             $recce->read(\$data);
78             #
79             # AST value
80             #
81             my $value = $recce->value();
82             croak 'Undefined AST value' if (! defined($value) || ! defined(${$value}));
83             #
84             # We want a single value
85             #
86             my $nextValue = $recce->value();
87             croak 'Ambiguous AST' if (defined($nextValue));
88             #
89             # Let's remember the latest AST
90             #
91             $self->{_ast} = ${$value};
92              
93             return $self;
94             }
95              
96              
97             sub ast {
98             my ($self) = @_;
99              
100             return $self->{_ast};
101             }
102              
103              
104             sub output {
105             my ($self) = @_;
106              
107             return $self->{_output};
108             }
109              
110              
111             sub generate {
112             my ($self, $ast, $template, $targetOptionHashp) = @_;
113              
114             $ast //= $self->ast();
115             $template //= 'moosex.tt2';
116             $targetOptionHashp //= {};
117              
118             if (ref($targetOptionHashp) ne 'HASH') {
119             croak '3rd argument must be a pointer to HASH';
120             }
121              
122             my $packageDist = __PACKAGE__;
123             $packageDist =~ s/::/-/g;
124             my $distDir = dist_dir($packageDist);
125             my $ttOptionHashp = $targetOptionHashp->{tt};
126             $ttOptionHashp->{STRICT} //= 1;
127             $ttOptionHashp->{DELIMITER} //= $Config{path_sep};
128             $ttOptionHashp->{INCLUDE_PATH} //= '';
129             $ttOptionHashp->{INCLUDE_PATH} .= $ttOptionHashp->{DELIMITER} . $distDir;
130             $ttOptionHashp->{INTERPOLATE} //= 1;
131             $ttOptionHashp->{EVAL_PERL} //= 1;
132             $ttOptionHashp->{PRE_CHOMP} //= CHOMP_NONE;
133             $ttOptionHashp->{POST_CHOMP} //= CHOMP_NONE;
134             $ttOptionHashp->{RELATIVE} //= 1;
135             local $Template::Directive::WHILE_MAX = 1000000000;
136             my $tt = Template->new($ttOptionHashp) || croak "$Template::ERROR";
137              
138             #
139             # The semantics for our TT templates is to provide a hash with
140             # a reference to a scratchpad hash (free to use) and the AST
141             #
142             my $ttVarsHashp = $targetOptionHashp->{vars};
143             #
144             # Our hooks
145             #
146             $ttVarsHashp->{ast} //= $ast;
147             $ttVarsHashp->{nativeFloat} = $targetOptionHashp->{nativeFloat} // 1;
148             $ttVarsHashp->{style} = $targetOptionHashp->{style} // 'Moose';
149              
150             $self->{_output} = '';
151             $tt->process($template, $ttVarsHashp, \$self->{_output}) || croak $tt->error();
152              
153             return $self;
154             }
155              
156              
157              
158             1;
159              
160             =pod
161              
162             =encoding UTF-8
163              
164             =head1 NAME
165              
166             MarpaX::Languages::IDL::AST - Translate an IDL source to an AST
167              
168             =head1 VERSION
169              
170             version 0.005
171              
172             =head1 SYNOPSIS
173              
174             use MarpaX::Languages::IDL::AST;
175              
176             my $idlPath = 'source.idl';
177             my $ast = MarpaX::Languages::IDL::AST->new()->parse($idlPath)->validate();
178              
179             =head2 $class->new()
180              
181             Instantiate a new object. Returns a reference to it, denoted $self hereafter.
182              
183             =head2 $self->parse($path, $hashOptPtr)
184              
185             Parse the IDL and produce an AST out of it, then a meta-AST that is more useful representation for further processing. Takes as parameters:
186              
187             =over
188              
189             =item $path
190              
191             A required IDL pathname.
192              
193             =item $hashOptPtr
194              
195             An optional reference to a hash containing Marpa::R2::Scanless::R() parameters, except the grammar and semantics_package options.
196              
197             =back
198              
199             The AST is an exact representation of the parse tree value of the IDL grammar contained in this package, except:
200              
201             =over
202              
203             =item scopedName
204              
205             Original grammar rule is:
206              
207             <scopedName> ::= <identifier> | '::' <identifier> | <scopedName> '::' <identifier>
208              
209             and has been rewriten to:
210              
211             <scopedName> ::= <identifier>+ separator => <coloncolon>
212              
213             A dedicated action rule will concatenate all identifiers into a single string, giving the impression that scopedName is a token (accurate terminology is a lexeme). I.e. the scopedName value in the AST is in the form:
214              
215             bless([start,totalLength,concatenatedValue], 'IDL::AST::scopedName')
216              
217             alike the identifier.
218              
219             =back
220              
221             This method returns $self.
222              
223             =head2 $self->ast()
224              
225             Returns the latest AST produced by $self->parse().
226              
227             =head2 $self->output()
228              
229             Returns the latest output produced by $self->generate().
230              
231             =head2 $self->generate($ast, $template, $targetOptionHashp)
232              
233             Generate files for the given AST $ast.
234              
235             =over
236              
237             =item $ast
238              
239             AST as produced by the method $self->parse(). Default to $self->ast().
240              
241             =item $template
242              
243             Template-Toolkit template name. Default to 'moosex.tt2', available in this distribution.
244              
245             =item $targetOptionHashp
246              
247             Hash reference of options specific to target $target.
248              
249             =back
250              
251             This method returns $self.
252              
253             =head1 DESCRIPTION
254              
255             This module provide and manage an AST of an IDL file, as per OMG's IDL 3.5 grammar specification.
256              
257             =head1 NOTES
258              
259             IDL version is 3.5 as of L<OMG IDL3.5 Specification|http://www.omg.org/spec/IDL35/3.5/>.
260              
261             This specification imposes input to come from a filename, with suffix '.idl'.
262              
263             Any preprocessing feature is ignored, and eventual multi-line proprocessing directives are likely to cause failure. Since the most expected preprocessing tokens are #include, #ifdef, and al., the user is expected to have already run a preprocessor before using this package.
264              
265             =head1 SEE ALSO
266              
267             L<Marpa::R2>
268              
269             =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
270              
271             =head1 SUPPORT
272              
273             =head2 Bugs / Feature Requests
274              
275             Please report any bugs or feature requests through the issue tracker
276             at L<https://rt.cpan.org/Public/Dist/Display.html?Name=MarpaX-Languages-IDL-AST>.
277             You will be notified automatically of any progress on your issue.
278              
279             =head2 Source Code
280              
281             This is open source software. The code repository is available for
282             public review and contribution under the terms of the license.
283              
284             L<https://github.com/jddurand/marpax-languages-idl-ast>
285              
286             git clone git://github.com/jddurand/marpax-languages-idl-ast.git
287              
288             =head1 AUTHOR
289              
290             Jean-Damien Durand <jeandamiendurand@free.fr>
291              
292             =head1 COPYRIGHT AND LICENSE
293              
294             This software is copyright (c) 2014 by Jean-Damien Durand.
295              
296             This is free software; you can redistribute it and/or modify it under
297             the same terms as the Perl 5 programming language system itself.
298              
299             =cut
300              
301             __DATA__
302             :default ::= action => [values] bless => ::lhs
303             lexeme default = action => [ start, length, value ] latm => 1 bless => ::name
304              
305             :start ::= <specification>
306              
307             <specification> ::= <supportedCppCommandAny> <importAny> <definitionMany>
308             <supportedCppCommandAny> ::= <supportedCppCommand>*
309             <supportedCppCommand> ::= CPPSTYLEDIRECTIVE
310             <definition> ::= <typeDcl> SEMICOLON
311             | <constDcl> SEMICOLON
312             | <exceptDcl> SEMICOLON
313             | <interface> SEMICOLON
314             | <module> SEMICOLON
315             | <value> SEMICOLON
316             | <typeIdDcl> SEMICOLON
317             | <typePrefixDcl> SEMICOLON
318             | <event> SEMICOLON
319             | <component> SEMICOLON
320             | <homeDcl> SEMICOLON
321             <module> ::= MODULE <identifier> LCURLY <definitionMany> RCURLY
322             <interface> ::= <interfaceDcl>
323             | <forwardDcl>
324             <interfaceDcl> ::= <interfaceHeader> LCURLY <interfaceBody> RCURLY
325             <forwardDcl> ::= <abstractOrLocalMaybe> INTERFACE <identifier>
326             <interfaceHeader> ::= <abstractOrLocalMaybe> INTERFACE <identifier> <interfaceInheritanceSpecMaybe>
327             <interfaceBody> ::= <export>*
328             <export> ::= <typeDcl> SEMICOLON
329             | <constDcl> SEMICOLON
330             | <exceptDcl> SEMICOLON
331             | <attrDcl> SEMICOLON
332             | <opDcl> SEMICOLON
333             | <typeIdDcl> SEMICOLON
334             | <typePrefixDcl> SEMICOLON
335             <interfaceInheritanceSpec> ::= COLON <interfaceNameListMany>
336             <interfaceName> ::= <scopedName>
337             #<scopedName> ::= <identifier>
338             # | COLONCOLON <identifier>
339             # | <scopedName> COLONCOLON <identifier>
340             <scopedName> ::= <identifier>+ separator => <coloncolon> action => _scopedName
341             <value> ::= <valueDcl>
342             | <valueAbsDcl>
343             | <valueBoxDcl>
344             | <valueForwardDcl>
345             <valueForwardDcl> ::= <abstractMaybe> VALUETYPE <identifier>
346             <valueBoxDcl> ::= VALUETYPE <identifier> <typeSpec>
347             <valueAbsDcl> ::= ABSTRACT VALUETYPE <identifier> <valueInheritanceSpecMaybe> LCURLY <exportAny> RCURLY
348             <valueDcl> ::= <valueHeader> LCURLY <valueElementAny> RCURLY
349             <valueHeader> ::= <customMaybe> VALUETYPE <identifier> <valueInheritanceSpecMaybe>
350             <valueInheritanceSpec> ::= <valueInheritanceSpec1ValuesMaybe> <valueInheritanceSpec2InterfacesMaybe>
351             <valueName> ::= <scopedName>
352             <valueElement> ::= <export>
353             | <stateMember>
354             | <initDcl>
355             <stateMember> ::= <publicOrPrivate> <typeSpec> <declarators> SEMICOLON
356             <initDcl> ::= FACTORY <identifier> LPAREN <initParamDeclsMaybe> RPAREN <raisesExprMaybe> SEMICOLON
357             <initParamDecls> ::= <initParamDeclListMany>
358             <initParamDecl> ::= <initParamAttribute> <paramTypeSpec> <simpleDeclarator>
359             <initParamAttribute> ::= IN
360             <constDcl> ::= CONST <constType> <identifier> EQUAL <constExp>
361             <constType> ::= <integerType>
362             | <charType>
363             | <wideCharType>
364             | <booleanType>
365             | <floatingPtType>
366             | <stringType>
367             | <wideStringType>
368             | <fixedPtConstType>
369             | <scopedName>
370             | <octetType>
371             <constExp> ::= <orExpr>
372             <orExpr> ::= <xorExpr>
373             | <orExpr> OR <xorExpr>
374             <xorExpr> ::= <andExpr>
375             | <xorExpr> XOR <andExpr>
376             <andExpr> ::= <shiftExpr>
377             | <andExpr> AND <shiftExpr>
378             <shiftExpr> ::= <addExpr>
379             | <shiftExpr> RSHIFT <addExpr>
380             | <shiftExpr> LSHIFT <addExpr>
381             <addExpr> ::= <multExpr>
382             | <addExpr> PLUS <multExpr>
383             | <addExpr> MINUS <multExpr>
384             <multExpr> ::= <unaryExpr>
385             | <multExpr> MUL <unaryExpr>
386             | <multExpr> DIV <unaryExpr>
387             | <multExpr> MOD <unaryExpr>
388             <unaryExpr> ::= <unaryOperator> <primaryExpr>
389             | <primaryExpr>
390             <unaryOperator> ::= MINUS
391             | PLUS
392             | TILDE
393             <primaryExpr> ::= <scopedName>
394             | <literal>
395             | LPAREN <constExp> RPAREN
396             <literal> ::= <integerLiteral>
397             | <stringLiteral>
398             | <wideStringLiteral>
399             | <characterLiteral>
400             | <wideCharacterLiteral>
401             | <fixedPtLiteral>
402             | <floatingPtLiteral>
403             | <booleanLiteral>
404             <booleanLiteral> ::= TRUE
405             | FALSE
406             <positiveIntConst> ::= <constExp>
407             <typeDcl> ::= TYPEDEF <typeDeclarator>
408             | <structType>
409             | <unionType>
410             | <enumType>
411             | NATIVE <simpleDeclarator>
412             | <constrForwardDecl>
413             <typeDeclarator> ::= <typeSpec> <declarators>
414             <typeSpec> ::= <simpleTypeSpec>
415             | <constrTypeSpec>
416             <simpleTypeSpec> ::= <baseTypeSpec>
417             | <templateTypeSpec>
418             | <scopedName>
419             <baseTypeSpec> ::= <floatingPtType>
420             | <integerType>
421             | <charType>
422             | <wideCharType>
423             | <booleanType>
424             | <octetType>
425             | <anyType>
426             | <objectType>
427             | <valueBaseType>
428             <templateTypeSpec> ::= <sequenceType>
429             | <stringType>
430             | <wideStringType>
431             | <fixedPtType>
432             <constrTypeSpec> ::= <structType>
433             | <unionType>
434             | <enumType>
435             <declarators> ::= <declaratorListMany>
436             <declarator> ::= <simpleDeclarator>
437             | <complexDeclarator>
438             <simpleDeclarator> ::= <identifier>
439             <complexDeclarator> ::= <arrayDeclarator>
440             <floatingPtType> ::= FLOAT
441             | DOUBLE
442             | LONG DOUBLE
443             <integerType> ::= <signedInt>
444             | <unsignedInt>
445             <signedInt> ::= <signedShortInt>
446             | <signedLongInt>
447             | <signedLonglongInt>
448             <signedShortInt> ::= SHORT
449             <signedLongInt> ::= LONG
450             <signedLonglongInt> ::= LONG LONG
451             <unsignedInt> ::= <unsignedShortInt>
452             | <unsignedLongInt>
453             | <unsignedLonglongInt>
454             <unsignedShortInt> ::= UNSIGNED SHORT
455             <unsignedLongInt> ::= UNSIGNED LONG
456             <unsignedLonglongInt> ::= UNSIGNED LONG LONG
457             <charType> ::= CHAR
458             <wideCharType> ::= WCHAR
459             <booleanType> ::= BOOLEAN
460             <octetType> ::= OCTET
461             <anyType> ::= ANY
462             <objectType> ::= OBJECT
463             <structType> ::= STRUCT <identifier> LCURLY <memberList> RCURLY
464             <memberList> ::= <member>+
465             <member> ::= <typeSpec> <declarators> SEMICOLON
466             <unionType> ::= UNION <identifier> SWITCH LPAREN <switchTypeSpec> RPAREN LCURLY <switchBody> RCURLY
467             <switchTypeSpec> ::= <integerType>
468             | <charType>
469             | <booleanType>
470             | <enumType>
471             | <scopedName>
472             <switchBody> ::= <case>+
473             <case> ::= <caseLabelMany> <elementSpec> SEMICOLON
474             <caseLabel> ::= CASE <constExp> COLON
475             | DEFAULT COLON
476             <elementSpec> ::= <typeSpec> <declarator>
477             <enumType> ::= ENUM <identifier> LCURLY <enumeratorListMany> RCURLY
478             <enumerator> ::= <identifier>
479             <sequenceType> ::= SEQUENCE LT <simpleTypeSpec> COMMA <positiveIntConst> GT
480             | SEQUENCE LT <simpleTypeSpec> GT
481             <stringType> ::= STRING LT <positiveIntConst> GT
482             | STRING
483             <wideStringType> ::= WSTRING LT <positiveIntConst> GT
484             | WSTRING
485             <arrayDeclarator> ::= <identifier> <fixedArraySizeMany>
486             <fixedArraySize> ::= LBRACKET <positiveIntConst> RBRACKET
487             <attrDcl> ::= <readonlyAttrSpec>
488             | <attrSpec>
489             <exceptDcl> ::= EXCEPTION <identifier> LCURLY <memberAny> RCURLY
490             <opDcl> ::= <opAttributeMaybe> <opTypeSpec> <identifier> <parameterDcls> <raisesExprMaybe> <contextExprMaybe>
491             <opAttribute> ::= ONEWAY
492             <opTypeSpec> ::= <paramTypeSpec>
493             | VOID
494             <parameterDcls> ::= LPAREN <paramDclListMany> RPAREN
495             | LPAREN RPAREN
496             <paramDcl> ::= <paramAttribute> <paramTypeSpec> <simpleDeclarator>
497             <paramAttribute> ::= IN
498             | OUT
499             | INOUT
500             <raisesExpr> ::= RAISES LPAREN <scopedNameListMany> RPAREN
501             <contextExpr> ::= CONTEXT LPAREN <stringLiteralListMany> RPAREN
502             <paramTypeSpec> ::= <baseTypeSpec>
503             | <stringType>
504             | <wideStringType>
505             | <scopedName>
506             <fixedPtType> ::= FIXED LT <positiveIntConst> COMMA <positiveIntConst> GT
507             <fixedPtConstType> ::= FIXED
508             <valueBaseType> ::= VALUEBASE
509             <constrForwardDecl> ::= STRUCT <identifier>
510             | UNION <identifier>
511             <import> ::= IMPORT <importedScope> SEMICOLON
512             <importedScope> ::= <scopedName>
513             | <stringLiteral>
514             <typeIdDcl> ::= TYPEID <scopedName> <stringLiteral>
515             <typePrefixDcl> ::= TYPEPREFIX <scopedName> <stringLiteral>
516             <readonlyAttrSpec> ::= READONLY ATTRIBUTE <paramTypeSpec> <readonlyAttrDeclarator>
517             <readonlyAttrDeclarator> ::= <simpleDeclarator> <raisesExpr>
518             | <simpleDeclaratorListMany>
519             <attrSpec> ::= ATTRIBUTE <paramTypeSpec> <attrDeclarator>
520             <attrDeclarator> ::= <simpleDeclarator> <attrRaisesExpr>
521             | <simpleDeclaratorListMany>
522             <attrRaisesExpr> ::= <getExcepExpr> <setExcepExprMaybe>
523             | <setExcepExpr>
524             <getExcepExpr> ::= GETRAISES <exceptionList>
525             <setExcepExpr> ::= SETRAISES <exceptionList>
526             <exceptionList> ::= LPAREN <scopedNameListMany> RPAREN
527              
528             # NOTE: Grammar rules 1 through 111 with the exception of the last three lines of rule 2 constitutes the portion of IDL that
529             # is not related to components.
530              
531             <component> ::= <componentDcl>
532             | <componentForwardDcl>
533             <componentForwardDcl> ::= COMPONENT <identifier>
534             <componentDcl> ::= <componentHeader> LCURLY <componentBody> RCURLY
535             <componentHeader> ::= COMPONENT <identifier> <componentInheritanceSpecMaybe> <supportedInterfaceSpecMaybe>
536             <supportedInterfaceSpec> ::= SUPPORTS <scopedNameListMany>
537             <componentInheritanceSpec> ::= COLON <scopedName>
538             <componentBody> ::= <componentExport>*
539             <componentExport> ::= <providesDcl> SEMICOLON
540             | <usesDcl> SEMICOLON
541             | <emitsDcl> SEMICOLON
542             | <publishesDcl> SEMICOLON
543             | <consumesDcl> SEMICOLON
544             | <attrDcl> SEMICOLON
545             <providesDcl> ::= PROVIDES <interfaceType> <identifier>
546             <interfaceType> ::= <scopedName>
547             | OBJECT
548             <usesDcl> ::= USES <multipleMaybe> <interfaceType> <identifier>
549             <emitsDcl> ::= EMITS <scopedName> <identifier>
550             <publishesDcl> ::= PUBLISHES <scopedName> <identifier>
551             <consumesDcl> ::= CONSUMES <scopedName> <identifier>
552             <homeDcl> ::= <homeHeader> <homeBody>
553             <homeHeader> ::= HOME <identifier> <homeInheritanceSpecMaybe> <supportedInterfaceSpecMaybe> MANAGES <scopedName> <primaryKeySpecMaybe>
554             <homeIinheritanceSpec> ::= COLON <scopedName>
555             <primaryKeySpec> ::= PRIMARYKEY <scopedName>
556             <homeBody> ::= LCURLY <homeExportAny> RCURLY
557             <homeExport> ::= <export>
558             | <factoryDcl> SEMICOLON
559             | <finderDcl> SEMICOLON
560             <factoryDcl> ::= FACTORY <identifier> LPAREN [ <initParamDecls> ] RPAREN <raisesExprMaybe>
561             <finderDcl> ::= FINDER <identifier> LPAREN [ <initParamDecls> ] RPAREN <raisesExprMaybe>
562             <event> ::= <eventDcl>
563             | <eventAbsDcl>
564             | <eventForwardDcl>
565             <eventForwardDcl> ::= <abstractMaybe> EVENTTYPE <identifier>
566             <eventAbsDcl> ::= ABSTRACT EVENTTYPE <identifier> <valueInheritanceSpecMaybe> LCURLY <exportAny> RCURLY
567             <eventDcl> ::= <eventHeader> LCURLY <valueElementAny> RCURLY
568             <eventHeader> ::= <customMaybe> EVENTTYPE <identifier> <valueInheritanceSpecMaybe>
569              
570             <importAny> ::= <import>*
571             <definitionMany> ::= <definition>+
572             <abstractOrLocal> ::= ABSTRACT | LOCAL
573             <abstractOrLocalMaybe> ::= <abstractOrLocal>
574             <abstractOrLocalMaybe> ::=
575             <interfaceInheritanceSpecMaybe> ::= <interfaceInheritanceSpec>
576             <interfaceInheritanceSpecMaybe> ::=
577             <interfaceNameListMany> ::= <interfaceName>+ separator => <comma>
578             <abstractMaybe> ::= ABSTRACT
579             <abstractMaybe> ::=
580             <valueInheritanceSpecMaybe> ::= <valueInheritanceSpec>
581             <valueInheritanceSpecMaybe> ::=
582             <exportAny> ::= <export>*
583             <valueElementAny> ::= <valueElement>*
584             <customMaybe> ::= CUSTOM
585             <customMaybe> ::=
586             <valueNameListMany> ::= <valueName>+ separator => <comma>
587             <truncatableMaybe> ::= TRUNCATABLE
588             <truncatableMaybe> ::=
589             <valueInheritanceSpec1Values> ::= COLON <truncatableMaybe> <valueNameListMany>
590             <valueInheritanceSpec1ValuesMaybe> ::= <valueInheritanceSpec1Values>
591             <valueInheritanceSpec1ValuesMaybe> ::=
592             <valueInheritanceSpec2Interfaces> ::= SUPPORTS <interfaceNameListMany>
593             <valueInheritanceSpec2InterfacesMaybe> ::= <valueInheritanceSpec2Interfaces>
594             <valueInheritanceSpec2InterfacesMaybe> ::=
595             <publicOrPrivate> ::= PUBLIC | PRIVATE
596             <initParamDeclsMaybe> ::= <initParamDecls>
597             <initParamDeclsMaybe> ::=
598             <raisesExprMaybe> ::= <raisesExpr>
599             <raisesExprMaybe> ::=
600             <initParamDeclListMany> ::= <initParamDecl>+ separator => <comma>
601             <declaratorListMany> ::= <declarator>+ separator => <comma>
602             <caseLabelMany> ::= <caseLabel>+
603             <enumeratorListMany> ::= <enumerator>+ separator => <comma>
604             <fixedArraySizeMany> ::= <fixedArraySize>+
605             <memberAny> ::= <member>*
606             <opAttributeMaybe> ::= <opAttribute>
607             <opAttributeMaybe> ::=
608             <contextExprMaybe> ::= <contextExpr>
609             <contextExprMaybe> ::=
610             <paramDclListMany> ::= <paramDcl>+ separator => <comma>
611             <scopedNameListMany> ::= <scopedName>+ separator => <comma>
612             <stringLiteralListMany> ::= <stringLiteral>+ separator => <comma>
613             <simpleDeclaratorListMany> ::= <simpleDeclarator>+ separator => <comma>
614             <setExcepExprMaybe> ::= <setExcepExpr>
615             <setExcepExprMaybe> ::=
616             <componentInheritanceSpecMaybe> ::= <componentInheritanceSpec>
617             <componentInheritanceSpecMaybe> ::=
618             <supportedInterfaceSpecMaybe> ::= <supportedInterfaceSpec>
619             <supportedInterfaceSpecMaybe> ::=
620             <multipleMaybe> ::= MULTIPLE
621             <multipleMaybe> ::=
622             <homeInheritanceSpecMaybe> ::= <homeIinheritanceSpec>
623             <homeInheritanceSpecMaybe> ::=
624             <primaryKeySpecMaybe> ::= <primaryKeySpec>
625             <primaryKeySpecMaybe> ::=
626             <homeExportAny> ::= <homeExport>*
627             <comma> ::= COMMA
628             <coloncolon> ::= COLONCOLON
629              
630             #
631             # Everything hardcoded is a lexeme, we want to have it blessed into an array
632             # The following is an exhaustive list of all IDL 3.5 keywords
633             #
634             SEMICOLON ~ ';'
635             MODULE ~ 'module'
636             LCURLY ~ '{'
637             RCURLY ~ '}'
638             INTERFACE ~ 'interface'
639             COLON ~ ':'
640             COLONCOLON ~ '::'
641             VALUETYPE ~ 'valuetype'
642             ABSTRACT ~ 'abstract'
643             FACTORY ~ 'factory'
644             LPAREN ~ '('
645             RPAREN ~ ')'
646             IN ~ 'in'
647             CONST ~ 'const'
648             EQUAL ~ '='
649             OR ~ '|'
650             XOR ~ '^'
651             AND ~ '&'
652             RSHIFT ~ '>>'
653             LSHIFT ~ '<<'
654             PLUS ~ '+'
655             MINUS ~ '-'
656             TILDE ~ '~'
657             MUL ~ '*'
658             DIV ~ '/'
659             MOD ~ '%'
660             TRUE ~ 'TRUE'
661             FALSE ~ 'FALSE'
662             TYPEDEF ~ 'typedef'
663             NATIVE ~ 'native'
664             FLOAT ~ 'float'
665             DOUBLE ~ 'double'
666             LONG ~ 'long'
667             SHORT ~ 'short'
668             UNSIGNED ~ 'unsigned'
669             CHAR ~ 'char'
670             WCHAR ~ 'wchar'
671             BOOLEAN ~ 'boolean'
672             OCTET ~ 'octet'
673             ANY ~ 'any'
674             OBJECT ~ 'Object'
675             STRUCT ~ 'struct'
676             UNION ~ 'union'
677             CASE ~ 'case'
678             DEFAULT ~ 'default'
679             ENUM ~ 'enum'
680             SEQUENCE ~ 'sequence'
681             LT ~ '<'
682             GT ~ '>'
683             SWITCH ~ 'switch'
684             COMMA ~ ','
685             STRING ~ 'string'
686             WSTRING ~ 'wstring'
687             LBRACKET ~ '['
688             RBRACKET ~ ']'
689             EXCEPTION ~ 'exception'
690             ONEWAY ~ 'oneway'
691             VOID ~ 'void'
692             OUT ~ 'out'
693             INOUT ~ 'inout'
694             RAISES ~ 'raises'
695             CONTEXT ~ 'context'
696             FIXED ~ 'fixed'
697             VALUEBASE ~ 'ValueBase'
698             IMPORT ~ 'import'
699             TYPEID ~ 'typeid'
700             TYPEPREFIX ~ 'typeprefix'
701             READONLY ~ 'readonly'
702             ATTRIBUTE ~ 'attribute'
703             GETRAISES ~ 'getraises'
704             SETRAISES ~ 'setraises'
705             COMPONENT ~ 'component'
706             SUPPORTS ~ 'supports'
707             PROVIDES ~ 'provides'
708             USES ~ 'uses'
709             EMITS ~ 'emits'
710             PUBLISHES ~ 'publishes'
711             CONSUMES ~ 'consumes'
712             HOME ~ 'home'
713             MANAGES ~ 'manages'
714             PRIMARYKEY ~ 'primarykey'
715             FINDER ~ 'finder'
716             EVENTTYPE ~ 'eventtype'
717             LOCAL ~ 'local'
718             CUSTOM ~ 'custom'
719             TRUNCATABLE ~ 'truncatable'
720             PUBLIC ~ 'public'
721             PRIVATE ~ 'private'
722             MULTIPLE ~ 'multiple'
723             #
724             # Copied from C language
725             #
726             <stringLiteral> ::= STRINGLITERALUNIT+
727             :lexeme ~ <STRINGLITERALUNIT>
728             STRING_LITERAL_INSIDE ~ [^"\\\n]
729             STRING_LITERAL_INSIDE ~ ES
730             STRING_LITERAL_INSIDE_any ~ STRING_LITERAL_INSIDE*
731             STRINGLITERALUNIT ~ SP_maybe '"' STRING_LITERAL_INSIDE_any '"' WS_any
732              
733             <wideStringLiteral> ::= WIDESTRINGLITERALUNIT+
734             :lexeme ~ <WIDESTRINGLITERALUNIT>
735             WIDESTRINGLITERALUNIT ~ SP_maybe 'L"' STRING_LITERAL_INSIDE_any '"' WS_any
736              
737             <integerLiteral> ::= ICONSTANT
738             :lexeme ~ <ICONSTANT>
739             ICONSTANT ~ HP H_many IS_maybe
740             | BP B_many IS_maybe # Gcc extension: binary constants
741             | NZ D_any IS_maybe
742             | '0' O_any IS_maybe
743             I_CONSTANT_INSIDE ~ [^'\\\n]
744             I_CONSTANT_INSIDE ~ ES
745             I_CONSTANT_INSIDE_many ~ I_CONSTANT_INSIDE+
746              
747             <identifier> ::= IDENTIFIER
748             :lexeme ~ <IDENTIFIER> priority => -1
749              
750             IDENTIFIER ~ L A_any
751              
752             #
753             # Original C includes this definition in ICONSTANT
754             #
755             <characterLiteral> ::= CHARACTERLITERAL
756             :lexeme ~ <CHARACTERLITERAL>
757             CHARACTERLITERAL ~ CP_maybe QUOTE I_CONSTANT_INSIDE_many QUOTE
758              
759             <wideCharacterLiteral> ::= WIDECHARACTERLITERAL
760             :lexeme ~ <WIDECHARACTERLITERAL>
761             WIDECHARACTERLITERAL ~ 'L' QUOTE I_CONSTANT_INSIDE_many QUOTE
762              
763             dD ~ [dD]
764             <fixedPtLiteral> ::= FIXEDPTLITERAL
765             :lexeme ~ <FIXEDPTLITERAL>
766             FIXEDPTLITERAL ~ D_many '.' D_many dD
767             | '.' D_many dD
768             | D_many '.' dD
769              
770             <floatingPtLiteral> ::= FCONSTANT
771             :lexeme ~ <FCONSTANT>
772             FCONSTANT ~ D_many E FS_maybe
773             | D_any '.' D_many E_maybe FS_maybe
774             | D_many '.' E_maybe FS_maybe
775             | HP H_many P FS_maybe
776             | HP H_any '.' H_many P FS_maybe
777             | HP H_many '.' P FS_maybe
778              
779             #
780             # G0 helpers
781             #
782             O ~ [0-7]
783             O_any ~ O*
784             D ~ [0-9]
785             D_any ~ D*
786             D_many ~ D+
787             NZ ~ [1-9]
788             L ~ [a-zA-Z_]
789             A ~ [a-zA-Z_0-9]
790             A_any ~ A*
791             H ~ [a-fA-F0-9]
792             H_any ~ H*
793             H_many ~ H+
794             HP ~ '0' [xX]
795             B ~ [0-1]
796             B_many ~ B+
797             BP ~ '0' [bB]
798             SIGN_maybe ~ [+-]
799             SIGN_maybe ~
800             E ~ [Ee] SIGN_maybe D_many
801             E_maybe ~ E
802             E_maybe ~
803             P ~ [Pp] SIGN_maybe D_many
804             FS ~ [fFlL]
805             FS_maybe ~ FS
806             FS_maybe ~
807             LL ~ 'll' | 'LL' | [lL]
808             LL_maybe ~ LL
809             LL_maybe ~
810             U ~ [uU]
811             U_maybe ~ U
812             U_maybe ~
813             IS ~ U LL_maybe | LL U_maybe
814             IS_maybe ~ IS
815             IS_maybe ~
816             CP ~ [uU] # L extracted - c.f. WIDECHARACTERLITERAL
817             CP_maybe ~ CP
818             CP_maybe ~
819             SP ~ 'u8' | [uUL]
820             SP_maybe ~ SP
821             SP_maybe ~
822             ES_AFTERBS ~ [\'\"\?\\abfnrtv]
823             | O
824             | O O
825             | O O O
826             | 'x' H_many
827             ES ~ BS ES_AFTERBS
828             WS ~ [ \t\v\n\f]
829             WS_any ~ WS*
830             WS_many ~ WS+
831             QUOTE ~ [']
832             BS ~ '\'
833              
834             #
835             # discards of the C language
836             #
837             ############################################################################
838             # Discard of a C comment, c.f. https://gist.github.com/jeffreykegler/5015057
839             ############################################################################
840             <C style comment> ~ '/*' <comment interior> '*/'
841             <comment interior> ~
842             <optional non stars>
843             <optional star prefixed segments>
844             <optional pre final stars>
845             <optional non stars> ~ [^*]*
846             <optional star prefixed segments> ~ <star prefixed segment>*
847             <star prefixed segment> ~ <stars> [^/*] <optional star free text>
848             <stars> ~ [*]+
849             <optional star free text> ~ [^*]*
850             <optional pre final stars> ~ [*]*
851             :discard ~ <C style comment>
852              
853             ##########################
854             # Discard of a C++ comment
855             ##########################
856             <Cplusplus style comment> ~ '//' <Cplusplus comment interior>
857             <Cplusplus comment interior> ~ [^\n]*
858             :discard ~ <Cplusplus style comment>
859              
860             ###########################
861             # TAKE CARE: preprocessor commands are IGNORED in this version
862             # Discard of a Perl comment
863             ###########################
864             <_Cpp style directive> ~ '#' <_Cpp style directive interior>
865             <_Cpp style directive interior> ~ [^\n]*
866             CPPSTYLEDIRECTIVE ~ <_Cpp style directive>
867             :discard ~ <_Cpp style directive>
868              
869             ####################
870             # WhiteSpace discard
871             ####################
872             :discard ~ WS_many # whitespace separates tokens
873