aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ic/src/icparse.yrl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ic/src/icparse.yrl')
-rw-r--r--lib/ic/src/icparse.yrl864
1 files changed, 864 insertions, 0 deletions
diff --git a/lib/ic/src/icparse.yrl b/lib/ic/src/icparse.yrl
new file mode 100644
index 0000000000..25b0f452e7
--- /dev/null
+++ b/lib/ic/src/icparse.yrl
@@ -0,0 +1,864 @@
+%%<copyright>
+%% <year>1997-2007</year>
+%% <holder>Ericsson AB, All Rights Reserved</holder>
+%%</copyright>
+%%<legalnotice>
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Initial Developer of the Original Code is Ericsson AB.
+%%</legalnotice>
+%%
+%%------------------------------------------------------------
+%% Yecc spec for IDL
+%%
+%%
+%%
+%% Implementation Detail:
+%% OorM_ means OneORMany and is used instead of
+%% the "+" BNF notation
+%% ZorM_ means ZeroORMany and is used instead of
+%% the "*" BNF notation
+%%
+%% All the reverse/1 calls are because yecc+lists naturally leads
+%% to reversed lists, which then have to be reversed. Maybe fix
+%% this?
+%%
+%% Implementation history
+%%
+%% The IDL language supported is not the complete IDL. We skipped
+%% the multiple declarator syntax allowed (i.e. typedef long T1,
+%% T2). This also applies to attributes members in structs,
+%% unions and exceptions, and to case labels in unions. The cases
+%% where IDL has been altered is marked with comments containing
+%% NIY.
+%%
+%% Above is chaging. Whenever we change a clause, we put (FIXED) in
+%% its comment.
+%%
+%%------------------------------------------------------------
+
+
+
+
+
+Nonterminals
+ '<op_type_spec>'
+ '<enumerator>'
+ '<switch_body>'
+ 'OorM_<case>'
+ '<member_list>'
+ '<struct_type>'
+ '<unsigned_int>'
+ '<constr_type_spec>'
+ '<shift_expr>'
+ '<or_expr>'
+ '<inheritance_spec>'
+ 'ZorM_<param_dcl>'
+ 'Opt_<context_expr>'
+ '<attr_dcl>'
+ '<array_declarator>'
+ '<element_spec>'
+ '<signed_int>'
+ '<primary_expr>'
+ '<interface_dcl>'
+ 'ZorM_<string_literal>'
+ 'Opt_<raises_expr>'
+ '<integer_type>'
+ '<signed_long_int>'
+ '<literal>'
+ '<export>'
+ '<forward_dcl>'
+ 'OorM_<definition>'
+ '<base_type_spec>'
+ '<op_dcl>'
+ '<const_exp>'
+ '<case>'
+ '<any_type>'
+ '<signed_short_int>'
+ '<unary_expr>'
+ '<context_expr>'
+ 'ZorM_<scoped_name>'
+ '<switch_type_spec>'
+ '<complex_declarator>'
+ '<declarators>'
+ 'OorM_<member>'
+ '<interface>'
+ '<parameter_dcls>'
+ '<op_attribute>'
+ '<positive_int_const>'
+ 'OorM_<fixed_array_size>'
+ '<sequence_type>'
+ '<case_label>'
+ '<octet_type>'
+ '<type_dcl>'
+ '<module>'
+ '<specification>'
+ '<declarator>'
+ '<boolean_type>'
+ '<union_type>'
+ '<add_expr>'
+ '<interface_body>'
+ '<except_dcl>'
+ '<fixed_array_size>'
+ '<unsigned_short_int>'
+ '<boolean_literal>'
+ '<and_expr>'
+ 'Opt_<inheritance_spec>'
+ '<scoped_name>'
+ '<param_type_spec>'
+ 'ZorM_<member>'
+ '<char_type>'
+ '<const_dcl>'
+ '<param_dcl>'
+ 'ZorM_<simple_declarator>'
+ 'ZorM_<declarator>'
+ '<const_type>'
+ '<definition>'
+ '<param_attribute>'
+ '<simple_declarator>'
+ 'Opt_readonly'
+ '<simple_type_spec>'
+ '<enum_type>'
+ '<type_spec>'
+ 'OorM_<case_label>'
+ '<floating_pt_type>'
+ '<template_type_spec>'
+ '<mult_expr>'
+ '<xor_expr>'
+ '<string_type>'
+ '<raises_expr>'
+ 'Opt_<op_attribute>'
+ 'ZorM_<enumerator>'
+ '<member>'
+ '<unsigned_long_int>'
+ '<type_declarator>'
+ '<unary_operator>'
+ 'ZorM_<export>'
+ '<interface_header>'
+ 'OE_preproc' % NON standard
+ 'OE_pragma' % NON standard
+ 'Ugly_pragmas' % NON standard
+ 'ZorM_<integer_literal>'
+ '<fixed_pt_type>'
+ '<fixed_pt_const_type>'
+ .
+
+
+Terminals
+ '#'
+ 'in'
+ '['
+ 'interface'
+ '('
+ 'case'
+ 'union'
+ 'struct'
+ '<character_literal>'
+ '<wcharacter_literal>'
+ ')'
+ ']'
+ 'any'
+ 'long'
+ 'float'
+ 'out'
+ '*'
+ '^'
+ 'enum'
+ 'double'
+ '+'
+ 'context'
+ 'oneway'
+ 'sequence'
+ ','
+ 'FALSE'
+ '<identifier>'
+ '{'
+ 'readonly'
+ ':'
+ '-'
+ 'void'
+ ';'
+ 'char'
+ 'wchar' %% WCHAR
+ '|'
+ 'inout'
+ '}'
+ 'attribute'
+ '<'
+ 'octet'
+ '/'
+ 'TRUE'
+ '~'
+ '='
+ '>'
+ 'switch'
+ 'unsigned'
+ 'typedef'
+ '>>'
+ 'const'
+ '<string_literal>'
+ '<wstring_literal>'
+ 'raises'
+ 'string'
+ 'wstring'
+ 'fixed'
+ 'default'
+ 'short'
+ '%'
+ '<<'
+ 'module'
+ 'exception'
+ 'boolean'
+ '<integer_literal>'
+ '<fixed_pt_literal>'
+ '<floating_pt_literal>'
+ '&'
+ '::'
+ 'Object'
+ .
+
+
+Rootsymbol '<specification>'.
+
+
+%%------------------------------------------------------------
+%% Clauses
+%%
+
+%% Handling of pragmas.
+%% Pragma prefix, id and version are not standard.
+
+%% pragma prefix, or codeopt
+OE_pragma -> '#' '<integer_literal>' '<identifier>'
+ '<identifier>' '<string_literal>' '#'
+ : #pragma{type='$4', to=followed, apply='$5'} .
+
+%% pragma id
+OE_pragma -> '#' '<integer_literal>' '<identifier>'
+ '<identifier>' '<identifier>' '<string_literal>' '#'
+ : #pragma{type='$4', to='$5', apply='$6'} .
+
+%% pragma version
+OE_pragma -> '#' '<integer_literal>' '<identifier>'
+ '<identifier>' '<identifier>' '<floating_pt_literal>' '#'
+ : #pragma{type='$4', to='$5', apply=ic_options:float_to_version('$6')} .
+
+
+
+
+
+
+
+%% Ugly pragmas
+Ugly_pragmas -> '$empty' : [].
+Ugly_pragmas -> 'Ugly_pragmas' 'OE_pragma' : ['$2'|'$1'].
+
+
+
+%% (0) Handling of preprocessor stuff.
+
+OE_preproc -> '#' '#' .
+
+OE_preproc -> '#' '<integer_literal>' '<string_literal>'
+ 'ZorM_<integer_literal>' '#'
+ : case '$4' of
+ [] ->
+ case '$2' of
+ {_,_,"1"} ->
+ #preproc{cat=line_nr, id='$3', aux='$4'};
+ _ ->
+ []
+ end;
+ _ ->
+ #preproc{cat=line_nr, id='$3', aux='$4'}
+ end.
+
+%% (0b) Non-standard
+'ZorM_<integer_literal>' -> '$empty' : [] .
+'ZorM_<integer_literal>' -> '<integer_literal>' 'ZorM_<integer_literal>'
+ : ['$1' | '$2'] .
+
+%% (1)
+'<specification>' -> 'OorM_<definition>' : reverse('$1') .
+
+
+%% Added clause
+'OorM_<definition>' -> '<definition>' : ['$1'] .
+'OorM_<definition>' -> 'OorM_<definition>' '<definition>'
+: ['$2' | '$1'] .
+
+
+%% (2)
+'<definition>' -> '<type_dcl>' ';' : '$1' .
+'<definition>' -> '<const_dcl>' ';' : '$1' .
+'<definition>' -> '<except_dcl>' ';' : '$1' .
+'<definition>' -> '<interface>' ';' : '$1' .
+'<definition>' -> '<module>' ';' : '$1' .
+'<definition>' -> 'OE_preproc' : '$1' .
+'<definition>' -> 'OE_pragma' : '$1' .
+
+
+%% (3)
+'<module>' -> 'module' '<identifier>' '{' 'OorM_<definition>' '}'
+: #module{ id='$2', body=reverse('$4')}.
+
+
+%% (4)
+'<interface>' -> '<interface_dcl>' : '$1' .
+'<interface>' -> '<forward_dcl>' : '$1' .
+
+
+%% (5)
+'<interface_dcl>' -> '<interface_header>' '{' '<interface_body>' '}'
+ : #interface{id=element(1, '$1'), inherit=element(2, '$1'),
+ body=lists:reverse('$3')} .
+
+
+%% (6)
+'<forward_dcl>' -> 'interface' '<identifier>'
+: #forward{id='$2'} .
+
+
+%% (7)
+'<interface_header>' -> 'interface' '<identifier>' 'Opt_<inheritance_spec>'
+: {'$2', '$3'} .
+
+
+%% (8)
+'<interface_body>' -> 'ZorM_<export>' : '$1' .
+
+
+%% Added clause
+'ZorM_<export>' -> '$empty' : [] .
+'ZorM_<export>' -> 'ZorM_<export>' '<export>'
+ %% Complicated because <export> might be a list (of type defs for instance)
+ : if is_list('$2') -> '$2' ++ '$1';
+ true -> ['$2' | '$1']
+ end .
+
+
+%% (9)
+'<export>' -> '<type_dcl>' ';' : '$1' .
+'<export>' -> '<const_dcl>' ';' : '$1' .
+'<export>' -> '<except_dcl>' ';' : '$1' .
+'<export>' -> '<attr_dcl>' ';' : '$1' .
+'<export>' -> '<op_dcl>' ';' : '$1' .
+'<export>' -> 'OE_preproc' : '$1' .
+'<export>' -> 'OE_pragma' : '$1' .
+
+%% Added clause
+'Opt_<inheritance_spec>' -> '$empty' : [].
+'Opt_<inheritance_spec>' -> '<inheritance_spec>' : '$1'.
+
+%% (10)
+'<inheritance_spec>' -> ':' '<scoped_name>' 'ZorM_<scoped_name>'
+ : ['$2' | reverse('$3')] .
+
+
+%% Added clause
+'ZorM_<scoped_name>' -> '$empty' : [] .
+'ZorM_<scoped_name>' -> 'ZorM_<scoped_name>' ',' '<scoped_name>'
+ : ['$3' | '$1'] .
+
+
+%% (11)
+'<scoped_name>' -> '<identifier>' : ic_symtab:scoped_id_new('$1') .
+'<scoped_name>' -> '::' '<identifier>' : ic_symtab:scoped_id_new_global('$2') .
+'<scoped_name>' -> '<scoped_name>' '::' '<identifier>'
+ : ic_symtab:scoped_id_add('$1', '$3') .
+
+
+%% (12)
+'<const_dcl>' -> 'const' '<const_type>' '<identifier>' '=' '<const_exp>'
+ : #const{type='$2', id='$3', val='$5'} .
+
+
+%% (13)
+'<const_type>' -> '<integer_type>' : '$1' .
+'<const_type>' -> '<char_type>' : '$1' .
+'<const_type>' -> '<boolean_type>' : '$1' .
+'<const_type>' -> '<floating_pt_type>' : '$1' .
+'<const_type>' -> '<string_type>' : '$1' .
+'<const_type>' -> '<fixed_pt_const_type>' : '$1' .
+'<const_type>' -> '<scoped_name>' : '$1' .
+'<const_type>' -> '<octet_type>' : '$1' .
+
+
+%% (14)
+'<const_exp>' -> '<or_expr>' : '$1' .
+
+
+%% (15)
+'<or_expr>' -> '<xor_expr>' : '$1' .
+'<or_expr>' -> '<or_expr>' '|' '<xor_expr>' : {'or', '$1', '$3'} .
+
+
+%% (16)
+'<xor_expr>' -> '<and_expr>' : '$1' .
+'<xor_expr>' -> '<xor_expr>' '^' '<and_expr>' : {'xor', '$1', '$3'} .
+
+
+%% (17)
+'<and_expr>' -> '<shift_expr>' : '$1' .
+'<and_expr>' -> '<and_expr>' '&' '<shift_expr>' : {'and', '$1', '$3'} .
+
+
+%% (18)
+'<shift_expr>' -> '<add_expr>' : '$1' .
+'<shift_expr>' -> '<shift_expr>' '>>' '<add_expr>' : {'rshift', '$1', '$3'} .
+'<shift_expr>' -> '<shift_expr>' '<<' '<add_expr>' : {'lshift', '$1', '$3'} .
+
+
+%% (19)
+'<add_expr>' -> '<mult_expr>' : '$1' .
+'<add_expr>' -> '<add_expr>' '+' '<mult_expr>' : {'+', '$1', '$3'} .
+'<add_expr>' -> '<add_expr>' '-' '<mult_expr>' : {'-', '$1', '$3'} .
+
+
+%% (20)
+'<mult_expr>' -> '<unary_expr>' : '$1' .
+'<mult_expr>' -> '<mult_expr>' '*' '<unary_expr>' : {'*', '$1', '$3'} .
+'<mult_expr>' -> '<mult_expr>' '/' '<unary_expr>' : {'/', '$1', '$3'} .
+'<mult_expr>' -> '<mult_expr>' '%' '<unary_expr>' : {'%', '$1', '$3'} .
+
+
+%% (21)
+'<unary_expr>' -> '<unary_operator>' '<primary_expr>' : {'$1', '$2'} .
+'<unary_expr>' -> '<primary_expr>' : '$1' .
+
+
+%% (22)
+'<unary_operator>' -> '-' : '$1' .
+'<unary_operator>' -> '+' : '$1' .
+'<unary_operator>' -> '~' : '$1' .
+
+
+%% (23)
+'<primary_expr>' -> '<scoped_name>' : '$1' .
+'<primary_expr>' -> '<literal>' : '$1' .
+'<primary_expr>' -> '(' '<const_exp>' ')' : '$2' .
+
+
+%% (24)
+'<literal>' -> '<integer_literal>' : '$1' .
+'<literal>' -> '<wstring_literal>' : '$1' .
+'<literal>' -> '<string_literal>' : '$1' .
+'<literal>' -> '<character_literal>' : '$1' .
+'<literal>' -> '<wcharacter_literal>' : '$1' .
+'<literal>' -> '<fixed_pt_literal>' : '$1' .
+'<literal>' -> '<floating_pt_literal>' : '$1' .
+'<literal>' -> '<boolean_literal>' : '$1' .
+
+
+%% (25)
+'<boolean_literal>' -> 'TRUE' : '$1' .
+'<boolean_literal>' -> 'FALSE' : '$1' .
+
+
+%% (26)
+'<positive_int_const>' -> '<const_exp>' : '$1' .
+
+
+%% (27)
+'<type_dcl>' -> 'typedef' '<type_declarator>' : '$2' .
+'<type_dcl>' -> '<struct_type>' : '$1' .
+'<type_dcl>' -> '<union_type>' : '$1' .
+'<type_dcl>' -> '<enum_type>' : '$1' .
+
+%% (28) NIY multiple declarators (FIXED)
+'<type_declarator>' -> '<type_spec>' '<declarators>'
+ : #typedef{type='$1', id='$2'} . %%%ic:unfold(#typedef{type='$1', id='$2'}) .
+%%'<type_declarator>' -> '<type_spec>' '<declarator>'
+%% : #typedef{type='$1', id='$2'} .
+
+%% (29)
+'<type_spec>' -> '<simple_type_spec>' : '$1' .
+'<type_spec>' -> '<constr_type_spec>' : '$1' .
+
+
+%% (30)
+'<simple_type_spec>' -> '<base_type_spec>' : '$1' .
+'<simple_type_spec>' -> '<template_type_spec>' : '$1' .
+'<simple_type_spec>' -> '<scoped_name>' : '$1' .
+
+
+%% (31)
+'<base_type_spec>' -> '<floating_pt_type>' : '$1' .
+'<base_type_spec>' -> '<integer_type>' : '$1' .
+'<base_type_spec>' -> '<char_type>' : '$1' .
+'<base_type_spec>' -> '<boolean_type>' : '$1' .
+'<base_type_spec>' -> '<octet_type>' : '$1' .
+'<base_type_spec>' -> '<any_type>' : '$1' .
+'<base_type_spec>' -> 'Object' : '$1' . %% NON Standard, isn't a base type
+
+
+%% (32)
+'<template_type_spec>' -> '<sequence_type>' : '$1' .
+'<template_type_spec>' -> '<string_type>' : '$1' .
+'<template_type_spec>' -> '<fixed_pt_type>' : '$1' .
+
+
+%% (33)
+'<constr_type_spec>' -> '<struct_type>' : '$1' .
+'<constr_type_spec>' -> '<union_type>' : '$1' .
+'<constr_type_spec>' -> '<enum_type>' : '$1' .
+
+
+%% (34)
+'<declarators>' -> '<declarator>' 'ZorM_<declarator>'
+: ['$1' | reverse('$2')] .
+
+%% Added clause
+'ZorM_<declarator>' -> '$empty' : [] .
+'ZorM_<declarator>' -> 'ZorM_<declarator>' ',' '<declarator>'
+: ['$3' | '$1'] .
+
+
+%% (35)
+'<declarator>' -> '<simple_declarator>' : '$1' .
+'<declarator>' -> '<complex_declarator>' : '$1' .
+
+
+%% (36)
+'<simple_declarator>' -> '<identifier>' : '$1' .
+
+
+%% (37)
+'<complex_declarator>' -> '<array_declarator>' : '$1' .
+
+
+%% (38)
+'<floating_pt_type>' -> 'float' : '$1' .
+'<floating_pt_type>' -> 'double' : '$1' .
+
+
+%% (39)
+'<integer_type>' -> '<signed_int>' : '$1' .
+'<integer_type>' -> '<unsigned_int>' : {'unsigned', '$1'} .
+
+
+%% (40)
+'<signed_int>' -> '<signed_long_int>' : '$1' .
+'<signed_int>' -> '<signed_short_int>' : '$1' .
+
+
+%% (41)
+'<signed_long_int>' -> 'long' : '$1' .
+'<signed_long_int>' -> 'long' 'long': {'long long', element(2,'$2')} .
+
+
+%% (42)
+'<signed_short_int>' -> 'short' : '$1' .
+
+
+%% (43)
+'<unsigned_int>' -> '<unsigned_long_int>' : '$1' .
+'<unsigned_int>' -> '<unsigned_short_int>' : '$1' .
+
+
+%% (44)
+'<unsigned_long_int>' -> 'unsigned' 'long' : '$2' .
+'<unsigned_long_int>' -> 'unsigned' 'long' 'long' : {'long long', element(2,'$2')} . %% ULLONG
+
+
+%% (45)
+'<unsigned_short_int>' -> 'unsigned' 'short' : '$2' .
+
+
+%% (46)
+'<char_type>' -> 'char' : '$1' .
+'<char_type>' -> 'wchar' : '$1' . %% WCHAR
+
+
+%% (47)
+'<boolean_type>' -> 'boolean' : '$1' .
+
+
+%% (48)
+'<octet_type>' -> 'octet' : '$1' .
+
+
+%% (49)
+'<any_type>' -> 'any' : '$1' .
+
+%%
+'<fixed_pt_const_type>' -> 'fixed' : '$1'.
+
+%% (50) NIY: unfolding of struct decls (FIXED)
+%%'<struct_type>' -> 'struct' '<identifier>' '{' '<member_list>' '}'
+%% : #struct{id='$2', body=ic:unfold('$4')} .
+'<struct_type>' -> 'struct' '<identifier>' '{' '<member_list>' '}'
+ : #struct{id='$2', body='$4'} .
+
+
+%% (51)
+'<member_list>' -> 'OorM_<member>' : reverse('$1') .
+
+
+%% Added clause
+%%'OorM_<member>' -> '<member>' : ['$1'] .
+%%'OorM_<member>' -> 'OorM_<member>' '<member>'
+%% : ['$2' | '$1'] .
+
+'OorM_<member>' -> '<member>' : '$1' .
+'OorM_<member>' -> 'OorM_<member>' '<member>'
+ : '$2' ++ '$1' .
+
+
+
+%% (52) NIY: member multiple declarators (FIXED)
+%%'<member>' -> '<type_spec>' '<declarators>' ';'
+%% : #member{type='$1', id='$2'} .
+
+'<member>' -> 'Ugly_pragmas' '<type_spec>' '<declarators>' 'Ugly_pragmas' ';' 'Ugly_pragmas'
+ : '$1' ++ '$4' ++ '$6' ++ [#member{type='$2', id='$3'}] .
+
+
+%% (53) NIY: unfolding of union cases (FIXED)
+%%'<union_type>' -> 'union' '<identifier>' 'switch'
+%% '(' '<switch_type_spec>' ')' '{' '<switch_body>' '}'
+%% : #union{id='$2', type='$5', body=ic:unfold('$8')} .
+'<union_type>' -> 'union' '<identifier>' 'switch'
+ '(' '<switch_type_spec>' ')' '{' '<switch_body>' '}'
+ : #union{id='$2', type='$5', body='$8'} .
+
+
+%% (54)
+'<switch_type_spec>' -> '<integer_type>' : '$1' .
+'<switch_type_spec>' -> '<char_type>' : '$1' .
+'<switch_type_spec>' -> '<boolean_type>' : '$1' .
+'<switch_type_spec>' -> '<enum_type>' : '$1' .
+'<switch_type_spec>' -> '<scoped_name>' : '$1' .
+
+
+%% (55)
+'<switch_body>' -> 'OorM_<case>' : reverse(lists:flatten('$1')) .
+
+%%'<switch_body>' -> 'OorM_<case>' : '$1' .
+
+
+%% Added clause
+'OorM_<case>' -> '<case>' : ['$1'] .
+'OorM_<case>' -> 'OorM_<case>' '<case>' : ['$2' | '$1'] .
+
+
+%% (56) NIY thing: multiple case labels (FIXED)
+%%'<case>' -> 'OorM_<case_label>' '<element_spec>' ';'
+%% : '$2'#case_dcl{label=reverse('$1')} .
+
+'<case>' ->
+ 'Ugly_pragmas' 'OorM_<case_label>'
+ 'Ugly_pragmas' '<element_spec>'
+ 'Ugly_pragmas' ';' 'Ugly_pragmas'
+ : '$1' ++ '$3' ++ '$5' ++ '$7' ++ [ '$4'#case_dcl{label=reverse('$2')} ] .
+
+
+%% Added clause
+%%'OorM_<case_label>' -> '<case_label>' : ['$1'] .
+%%'OorM_<case_label>' -> 'OorM_<case_label>' '<case_label>' : ['$2' | '$1'] .
+
+'OorM_<case_label>' -> 'Ugly_pragmas' '<case_label>' 'Ugly_pragmas'
+ : '$1' ++ ['$2'] ++ '$3' .
+'OorM_<case_label>' -> 'OorM_<case_label>' 'Ugly_pragmas' '<case_label>' 'Ugly_pragmas'
+ : '$2' ++ ['$3'|'$1'] ++ '$4'.
+
+
+%% (57)
+'<case_label>' -> 'case' '<const_exp>' ':' : '$2' .
+'<case_label>' -> 'default' ':' : '$1' .
+
+
+%% (58)
+'<element_spec>' -> '<type_spec>' '<declarator>'
+: #case_dcl{type='$1', id='$2'} .
+
+
+%% (59)
+%%'<enum_type>' -> 'enum' '<identifier>'
+%%'{' '<enumerator>' 'ZorM_<enumerator>' '}'
+%%: #enum{id='$2', body=['$4' | reverse('$5')]} .
+
+'<enum_type>' -> 'enum' '<identifier>'
+'{' 'Ugly_pragmas' '<enumerator>' 'Ugly_pragmas' 'ZorM_<enumerator>' 'Ugly_pragmas' '}'
+: #enum{id='$2', body='$4'++'$6'++'$8'++['$5' | reverse('$7')]} .
+
+
+
+%% Added clause
+%%'ZorM_<enumerator>' -> '$empty' : [] .
+%%'ZorM_<enumerator>' -> 'ZorM_<enumerator>' ',' '<enumerator>' : ['$3' | '$1'] .
+
+'ZorM_<enumerator>' -> '$empty' : [] .
+'ZorM_<enumerator>' -> 'ZorM_<enumerator>' 'Ugly_pragmas' ',' 'Ugly_pragmas' '<enumerator>'
+ : '$2'++'$4'++['$5' | '$1'] .
+
+%% (60)
+'<enumerator>' -> '<identifier>' : #enumerator{id='$1'} .
+
+
+%% (61)
+'<sequence_type>' -> 'sequence' '<' '<simple_type_spec>' ','
+ '<positive_int_const>' '>'
+ : #sequence{type='$3', length='$5'} .
+'<sequence_type>' -> 'sequence' '<' '<simple_type_spec>' '>'
+ : #sequence{type='$3'} .
+
+
+%% (62)
+'<string_type>' -> 'string' '<' '<positive_int_const>' '>'
+ : #string{length='$3'} .
+'<string_type>' -> 'string' : #string{} .
+
+'<string_type>' -> 'wstring' '<' '<positive_int_const>' '>' %% WSTRING
+ : #wstring{length='$3'} .
+'<string_type>' -> 'wstring' : #wstring{} . %% WSTRING
+
+
+%% (63)
+'<array_declarator>' -> '<identifier>' 'OorM_<fixed_array_size>'
+ : #array{id='$1', size=reverse('$2')} .
+
+
+%% Added clause
+'OorM_<fixed_array_size>' -> '<fixed_array_size>' : ['$1'] .
+'OorM_<fixed_array_size>' -> 'OorM_<fixed_array_size>' '<fixed_array_size>'
+ : ['$2' | '$1'] .
+
+
+%% (64)
+'<fixed_array_size>' -> '[' '<positive_int_const>' ']' : '$2' .
+
+
+%% (65) NIY: multiple attribute declarators (FIXED)
+'<attr_dcl>' -> 'Opt_readonly' 'attribute' '<param_type_spec>'
+ '<simple_declarator>' 'ZorM_<simple_declarator>'
+ : #attr{readonly='$1', type='$3', id=['$4' | reverse('$5')]} .
+%% : ic:unfold(#attr{readonly='$1', type='$3', id=['$4' | reverse('$5')]}) .
+%%'<attr_dcl>' -> 'Opt_readonly' 'attribute' '<param_type_spec>'
+%% '<simple_declarator>'
+
+
+%% (66) NIY: unfolding of exception bodies (FIXED)
+%%'<except_dcl>' -> 'exception' '<identifier>' '{' 'ZorM_<member>' '}'
+%% : #except{id='$2', body=ic:unfold('$4')} .
+'<except_dcl>' -> 'exception' '<identifier>' '{' 'ZorM_<member>' '}'
+ : #except{id='$2', body=reverse('$4')} .
+
+%% (67)
+'<op_dcl>' -> 'Opt_<op_attribute>' '<op_type_spec>' '<identifier>' '<parameter_dcls>' 'Opt_<raises_expr>' 'Opt_<context_expr>'
+ : #op{oneway='$1', type='$2', id='$3', params='$4', raises='$5', ctx='$6'} .
+
+%% Added clause
+'Opt_<op_attribute>' -> '$empty' : nil.
+'Opt_<op_attribute>' -> '<op_attribute>' : '$1'.
+
+%% (68)
+'<op_attribute>' -> 'oneway' : '$1' .
+
+
+%% (69)
+'<op_type_spec>' -> '<param_type_spec>' : '$1' .
+'<op_type_spec>' -> 'void' : '$1' .
+
+
+%% (70) Rewritten
+%'<parameter_dcls>' -> '(' '<param_dcl>' 'ZorM_<param_dcl>' ')'
+% : ['$2' | reverse('$3')] .
+%'<parameter_dcls>' -> '(' ')' : [] .
+
+'<parameter_dcls>' -> '(' 'Ugly_pragmas' '<param_dcl>' 'ZorM_<param_dcl>' ')'
+ : '$2' ++ ['$3' | reverse('$4')] .
+'<parameter_dcls>' -> '(' 'Ugly_pragmas' ')' : '$2' .
+
+
+%% Added clause
+%'ZorM_<param_dcl>' -> '$empty' : [] .
+%'ZorM_<param_dcl>' -> 'ZorM_<param_dcl>' ',' '<param_dcl>' : ['$3' | '$1'] .
+
+
+'ZorM_<param_dcl>' -> 'Ugly_pragmas' : '$1' .
+'ZorM_<param_dcl>' -> 'ZorM_<param_dcl>' 'Ugly_pragmas' ',' 'Ugly_pragmas' '<param_dcl>' 'Ugly_pragmas'
+ : '$2' ++ '$4' ++ '$6' ++ ['$5' | '$1'] .
+
+
+
+
+%% (71)
+'<param_dcl>' -> '<param_attribute>' '<param_type_spec>' '<simple_declarator>'
+ : #param{inout='$1', type='$2', id='$3'} .
+
+
+%% (72)
+'<param_attribute>' -> 'in' : '$1' .
+'<param_attribute>' -> 'out' : '$1' .
+'<param_attribute>' -> 'inout' : '$1' .
+
+
+%% Added clause
+'Opt_<raises_expr>' -> '$empty' : [] .
+'Opt_<raises_expr>' -> '<raises_expr>' : '$1' .
+
+%% (73)
+'<raises_expr>' -> 'raises' '(' '<scoped_name>' 'ZorM_<scoped_name>' ')'
+ : ['$3'| reverse('$4')] .
+
+
+%% Added clause
+'Opt_<context_expr>' -> '$empty' : [] .
+'Opt_<context_expr>' -> '<context_expr>' : '$1'.
+
+%% (74)
+'<context_expr>' -> 'context' '(' '<string_literal>' 'ZorM_<string_literal>'')'
+ : ['$3' | reverse('$4')] .
+
+
+
+%% (75)
+'<param_type_spec>' -> '<base_type_spec>' : '$1' .
+'<param_type_spec>' -> '<string_type>' : '$1' .
+'<param_type_spec>' -> '<scoped_name>' : '$1' .
+
+
+%% (96)
+'<fixed_pt_type>' -> 'fixed' '<' '<positive_int_const>' ',' '<positive_int_const>' '>'
+ : #fixed{digits='$3',scale='$5'} .
+
+
+%% Added clause
+'ZorM_<string_literal>' -> '$empty' : [] .
+'ZorM_<string_literal>' -> 'ZorM_<string_literal>' ',' '<string_literal>'
+ : ['$3' | '$1'] .
+
+%% Added clause
+'ZorM_<simple_declarator>' -> '$empty' : [] .
+'ZorM_<simple_declarator>' -> 'ZorM_<simple_declarator>' ','
+'<simple_declarator>' : ['$3' | '$1'] .
+
+%% Added clause
+%%'ZorM_<member>' -> '$empty' : [] .
+%%'ZorM_<member>' -> 'ZorM_<member>' '<member>' : ['$2' | '$1'] .
+
+'ZorM_<member>' -> 'Ugly_pragmas' : '$1' .
+'ZorM_<member>' -> 'ZorM_<member>' '<member>' : '$2' ++ '$1' .
+
+
+%% Added clause
+'Opt_readonly' -> '$empty' : nil.
+'Opt_readonly' -> 'readonly' : '$1'.
+
+
+
+Erlang code.
+%%-----------------------------------------------------------
+
+
+