rgen 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. data/CHANGELOG +20 -1
  2. data/MIT-LICENSE +1 -1
  3. data/README +12 -9
  4. data/lib/instantiators/ea_instantiator.rb +36 -0
  5. data/lib/metamodels/uml13_metamodel.rb +559 -0
  6. data/lib/metamodels/uml13_metamodel_ext.rb +26 -0
  7. data/lib/mmgen/metamodel_generator.rb +5 -5
  8. data/lib/mmgen/mm_ext/ecore_ext.rb +95 -0
  9. data/lib/mmgen/mmgen.rb +6 -4
  10. data/lib/mmgen/templates/annotations.tpl +37 -0
  11. data/lib/mmgen/templates/metamodel_generator.tpl +171 -0
  12. data/lib/rgen/ecore/ecore.rb +190 -0
  13. data/lib/rgen/ecore/ecore_instantiator.rb +25 -0
  14. data/lib/rgen/ecore/ecore_transformer.rb +85 -0
  15. data/lib/rgen/environment.rb +9 -24
  16. data/lib/rgen/find_helper.rb +68 -0
  17. data/lib/rgen/{instantiator.rb → instantiator/abstract_instantiator.rb} +6 -2
  18. data/lib/rgen/instantiator/abstract_xml_instantiator.rb +59 -0
  19. data/lib/rgen/instantiator/default_xml_instantiator.rb +117 -0
  20. data/lib/rgen/instantiator/ecore_xml_instantiator.rb +144 -0
  21. data/lib/rgen/instantiator/nodebased_xml_instantiator.rb +157 -0
  22. data/lib/rgen/instantiator/xmi11_instantiator.rb +164 -0
  23. data/lib/rgen/metamodel_builder.rb +103 -9
  24. data/lib/rgen/metamodel_builder/build_helper.rb +26 -4
  25. data/lib/rgen/metamodel_builder/builder_extensions.rb +285 -88
  26. data/lib/rgen/metamodel_builder/builder_runtime.rb +7 -1
  27. data/lib/rgen/metamodel_builder/data_types.rb +67 -0
  28. data/lib/rgen/metamodel_builder/intermediate/annotation.rb +30 -0
  29. data/lib/rgen/metamodel_builder/metamodel_description.rb +232 -0
  30. data/lib/rgen/metamodel_builder/mm_multiple.rb +23 -0
  31. data/lib/rgen/metamodel_builder/module_extension.rb +33 -0
  32. data/lib/rgen/model_comparator.rb +56 -0
  33. data/lib/rgen/model_dumper.rb +5 -5
  34. data/lib/rgen/name_helper.rb +17 -1
  35. data/lib/rgen/template_language.rb +148 -28
  36. data/lib/rgen/template_language/directory_template_container.rb +56 -38
  37. data/lib/rgen/template_language/output_handler.rb +93 -77
  38. data/lib/rgen/template_language/template_container.rb +186 -143
  39. data/lib/rgen/transformer.rb +19 -14
  40. data/lib/transformers/uml13_to_ecore.rb +75 -0
  41. data/redist/xmlscan/ChangeLog +1301 -0
  42. data/redist/xmlscan/README +34 -0
  43. data/redist/xmlscan/THANKS +11 -0
  44. data/redist/xmlscan/doc/changes.html +74 -0
  45. data/redist/xmlscan/doc/changes.rd +80 -0
  46. data/redist/xmlscan/doc/en/conformance.html +136 -0
  47. data/redist/xmlscan/doc/en/conformance.rd +152 -0
  48. data/redist/xmlscan/doc/en/manual.html +356 -0
  49. data/redist/xmlscan/doc/en/manual.rd +402 -0
  50. data/redist/xmlscan/doc/ja/conformance.ja.html +118 -0
  51. data/redist/xmlscan/doc/ja/conformance.ja.rd +134 -0
  52. data/redist/xmlscan/doc/ja/manual.ja.html +325 -0
  53. data/redist/xmlscan/doc/ja/manual.ja.rd +370 -0
  54. data/redist/xmlscan/doc/src/Makefile +41 -0
  55. data/redist/xmlscan/doc/src/conformance.rd.src +256 -0
  56. data/redist/xmlscan/doc/src/langsplit.rb +110 -0
  57. data/redist/xmlscan/doc/src/manual.rd.src +614 -0
  58. data/redist/xmlscan/install.rb +41 -0
  59. data/redist/xmlscan/lib/xmlscan/encoding.rb +311 -0
  60. data/redist/xmlscan/lib/xmlscan/htmlscan.rb +289 -0
  61. data/redist/xmlscan/lib/xmlscan/namespace.rb +352 -0
  62. data/redist/xmlscan/lib/xmlscan/parser.rb +299 -0
  63. data/redist/xmlscan/lib/xmlscan/scanner.rb +1109 -0
  64. data/redist/xmlscan/lib/xmlscan/version.rb +22 -0
  65. data/redist/xmlscan/lib/xmlscan/visitor.rb +158 -0
  66. data/redist/xmlscan/lib/xmlscan/xmlchar.rb +441 -0
  67. data/redist/xmlscan/memo/CONFORMANCE +1249 -0
  68. data/redist/xmlscan/memo/PRODUCTIONS +195 -0
  69. data/redist/xmlscan/memo/contentspec.ry +335 -0
  70. data/redist/xmlscan/samples/chibixml.rb +105 -0
  71. data/redist/xmlscan/samples/getxmlchar.rb +122 -0
  72. data/redist/xmlscan/samples/rexml.rb +159 -0
  73. data/redist/xmlscan/samples/xmlbench.rb +88 -0
  74. data/redist/xmlscan/samples/xmlbench/parser/chibixml.rb +22 -0
  75. data/redist/xmlscan/samples/xmlbench/parser/nqxml.rb +29 -0
  76. data/redist/xmlscan/samples/xmlbench/parser/rexml.rb +62 -0
  77. data/redist/xmlscan/samples/xmlbench/parser/xmlparser.rb +22 -0
  78. data/redist/xmlscan/samples/xmlbench/parser/xmlscan-0.0.10.rb +62 -0
  79. data/redist/xmlscan/samples/xmlbench/parser/xmlscan-chibixml.rb +22 -0
  80. data/redist/xmlscan/samples/xmlbench/parser/xmlscan-rexml.rb +22 -0
  81. data/redist/xmlscan/samples/xmlbench/parser/xmlscan.rb +99 -0
  82. data/redist/xmlscan/samples/xmlbench/xmlbench-lib.rb +116 -0
  83. data/redist/xmlscan/samples/xmlconftest.rb +200 -0
  84. data/redist/xmlscan/test.rb +7 -0
  85. data/redist/xmlscan/tests/deftestcase.rb +73 -0
  86. data/redist/xmlscan/tests/runtest.rb +47 -0
  87. data/redist/xmlscan/tests/testall.rb +14 -0
  88. data/redist/xmlscan/tests/testencoding.rb +438 -0
  89. data/redist/xmlscan/tests/testhtmlscan.rb +752 -0
  90. data/redist/xmlscan/tests/testnamespace.rb +457 -0
  91. data/redist/xmlscan/tests/testparser.rb +591 -0
  92. data/redist/xmlscan/tests/testscanner.rb +1749 -0
  93. data/redist/xmlscan/tests/testxmlchar.rb +143 -0
  94. data/redist/xmlscan/tests/visitor.rb +34 -0
  95. data/test/array_extensions_test.rb +2 -2
  96. data/test/ea_instantiator_test.rb +41 -0
  97. data/test/ecore_self_test.rb +53 -0
  98. data/test/environment_test.rb +11 -6
  99. data/test/metamodel_builder_test.rb +404 -245
  100. data/test/metamodel_roundtrip_test.rb +52 -0
  101. data/test/metamodel_roundtrip_test/TestModel.rb +65 -0
  102. data/test/metamodel_roundtrip_test/TestModel_Regenerated.rb +64 -0
  103. data/test/metamodel_roundtrip_test/houseMetamodel.ecore +32 -0
  104. data/test/metamodel_roundtrip_test/houseMetamodel_from_ecore.rb +39 -0
  105. data/test/rgen_test.rb +3 -3
  106. data/test/template_language_test.rb +65 -39
  107. data/test/template_language_test/expected_result.txt +24 -3
  108. data/test/template_language_test/templates/code/array.tpl +11 -0
  109. data/test/template_language_test/templates/content/author.tpl +7 -0
  110. data/test/template_language_test/templates/content/chapter.tpl +1 -1
  111. data/test/template_language_test/templates/root.tpl +17 -8
  112. data/test/template_language_test/testout.txt +24 -3
  113. data/test/testmodel/class_model_checker.rb +119 -0
  114. data/test/{xmi_instantiator_test/testmodel.eap → testmodel/ea_testmodel.eap} +0 -0
  115. data/test/{xmi_instantiator_test/testmodel.xml → testmodel/ea_testmodel.xml} +81 -14
  116. data/test/testmodel/ea_testmodel_partial.xml +317 -0
  117. data/test/testmodel/ecore_model_checker.rb +101 -0
  118. data/test/testmodel/manual_testmodel.xml +22 -0
  119. data/test/testmodel/object_model_checker.rb +67 -0
  120. data/test/transformer_test.rb +18 -10
  121. data/test/xml_instantiator_test.rb +81 -8
  122. data/test/xml_instantiator_test/simple_ecore_model_checker.rb +94 -0
  123. data/test/xml_instantiator_test/simple_xmi_ecore_instantiator.rb +53 -0
  124. data/test/xml_instantiator_test/simple_xmi_metamodel.rb +49 -0
  125. data/test/xml_instantiator_test/simple_xmi_to_ecore.rb +75 -0
  126. metadata +126 -28
  127. data/lib/ea/xmi_class_instantiator.rb +0 -46
  128. data/lib/ea/xmi_helper.rb +0 -26
  129. data/lib/ea/xmi_metamodel.rb +0 -34
  130. data/lib/ea/xmi_object_instantiator.rb +0 -46
  131. data/lib/ea/xmi_to_classmodel.rb +0 -78
  132. data/lib/ea/xmi_to_objectmodel.rb +0 -92
  133. data/lib/mmgen/mm_ext/uml_classmodel_ext.rb +0 -71
  134. data/lib/mmgen/templates/uml_classmodel.tpl +0 -63
  135. data/lib/rgen/xml_instantiator.rb +0 -132
  136. data/lib/uml/objectmodel_instantiator.rb +0 -53
  137. data/lib/uml/uml_classmodel.rb +0 -92
  138. data/lib/uml/uml_objectmodel.rb +0 -65
  139. data/test/metamodel_generator_test.rb +0 -44
  140. data/test/metamodel_generator_test/TestModel.rb +0 -40
  141. data/test/metamodel_generator_test/expected_result.txt +0 -40
  142. data/test/xmi_class_instantiator_test.rb +0 -24
  143. data/test/xmi_instantiator_test/class_model_checker.rb +0 -97
  144. data/test/xmi_object_instantiator_test.rb +0 -65
  145. data/test/xml_instantiator_test/testmodel.xml +0 -7
@@ -0,0 +1,195 @@
1
+ $Id: PRODUCTIONS,v 1.3 2003/01/19 14:35:49 katsu Exp $
2
+
3
+ == $B<BAu$N40N;$7$F$$$k$b$N!#(B
4
+
5
+ $B$3$l$i$N@8@.5,B'$K%^%C%A$9$k$3$H$,4|BT$5$l$kJ8L.$K$*$$$F!"4|BT$5$l$k@8@.5,B'$K(B
6
+ $B%^%C%A$7$J$+$C$?>l9g$O!">o$K(B parse error $B$H$J$k!#(B
7
+
8
+
9
+ XMLScan::XMLScanner $B$G<BAu$5$l$F$$$k$b$N!#(B
10
+
11
+ [10] AttValue ::= '"' ([^<&"] | Reference)* '"'
12
+ | ("'" ([^<&'] | Reference)* "'")
13
+ [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
14
+ [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
15
+ [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))?
16
+ '?>'
17
+ [18] CDSect ::= CDStart CData CDEnd
18
+ [19] CDStart ::= '<![CDATA['
19
+ [20] CData ::= (Char* - (Char* ']]>' Char*))
20
+ [21] CDEnd ::= ']]>'
21
+ [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
22
+ [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
23
+ [24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'" |
24
+ '"' VersionNum '"')
25
+ [32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'")
26
+ | ('"' ('yes' | 'no') '"'))
27
+ [40] STag ::= '<' Name (S Attribute)* S? '>'
28
+ [41] Attribute ::= Name Eq AttValue
29
+ [42] ETag ::= '</' Name S? '>'
30
+ [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
31
+ [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
32
+ [68] EntityRef ::= '&' Name ';'
33
+ [80] EncodingDecl ::= S 'encoding' Eq
34
+ ('"' EncName '"' | "'" EncName "'")
35
+
36
+
37
+ XMLScan::XMLParser $B$G<BAu$5$l$F$$$k$b$N!#(B
38
+
39
+ [1] document ::= prolog element Misc*
40
+ [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
41
+ [43] content ::= CharData? ((element | Reference | CDSect | PI
42
+ | Comment) CharData?)*
43
+ [39] element ::= EmptyElemTag | STag content ETag
44
+
45
+
46
+
47
+
48
+ == $B<BAu$7$F$$$k$,!"B>$N@8@.5,B'Cf$K%$%s%i%$%s$GE83+$7$?$b$N!#(B
49
+
50
+ XMLScan::XMLScanner $B$G<BAu$5$l$F$$$k$b$N!#(B
51
+
52
+ [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
53
+ [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
54
+ [25] Eq ::= S? '=' S?
55
+ [27] Misc ::= Comment | PI | S
56
+ [67] Reference ::= EntityRef | CharRef
57
+ [75] ExternalID ::= 'SYSTEM' S SystemLiteral
58
+ | 'PUBLIC' S PubidLiteral S SystemLiteral
59
+
60
+
61
+
62
+
63
+ == $B<BAu$7$F$$$k$,!"@8@.5,B'$K<c43JQ99$r2C$($F$$$k$b$N!#(B
64
+
65
+ XMLScan::XMLScanner $B$O(B ExternalID $B$N@8@.5,B'$r(B
66
+ ExternalID ::= 'SYSTEM' S SystemLiteral
67
+ | 'PUBLIC' S PubidLiteral S SystemLiteral?
68
+ $B$H$7$F2r@O!#(BXMLScan::XMLParser $B$,(B SystemLiteral $B$r;}$?$J$$8x3+<1JL;R$N(B
69
+ $B%A%'%C%/$r9T$&!#(B
70
+
71
+ [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
72
+ ('[' (markupdecl | DeclSep)* ']' S?)? '>'
73
+
74
+
75
+
76
+
77
+ == $BL$Ce<j$@$,Ce<jM=Dj$N$b$N!#(B
78
+
79
+ $BFbIt(B DTD $B%5%V%;%C%H$K4X$9$k$b$N!#(B
80
+
81
+ [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
82
+ | ("'" ([^%&'] | PEReference | Reference)* "'")
83
+ [28a] DeclSep ::= PEReference | S
84
+ [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl
85
+ | NotationDecl | PI | Comment
86
+ [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
87
+ [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
88
+ [53] AttDef ::= S Name S AttType S DefaultDecl
89
+ [54] AttType ::= StringType | TokenizedType | EnumeratedType
90
+ [55] StringType ::= 'CDATA'
91
+ [56] TokenizedType ::= 'ID'
92
+ [57] EnumeratedType ::= NotationType | Enumeration
93
+ [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
94
+ [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
95
+ [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue
96
+ [69] PEReference ::= '%' Name ';'
97
+ [70] EntityDecl ::= GEDecl | PEDecl
98
+ [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
99
+ [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
100
+ [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
101
+ [74] PEDef ::= EntityValue | ExternalID
102
+ [76] NDataDecl ::= S 'NDATA' S Name
103
+ [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID | PublicID)
104
+ S? '>'
105
+ [83] PublicID ::= 'PUBLIC' S PubidLiteral
106
+
107
+
108
+
109
+ == $BCe<jM=DjL5$+$C$?$1$ICe<j$7$A$c$C$?$b$N!#(B
110
+
111
+ $BMWAGFbMF%b%G%k$N@53N$J9=J82r@O$O$d$i$J$$$+$b!#(B
112
+ $B$C$F8@$C$F$?$N$K(B($B>P(B)$B!#(B> contentspec.ry
113
+
114
+ [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
115
+ [47] children ::= (choice | seq) ('?' | '*' | '+')?
116
+ [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
117
+ [49] choice ::= '(' S? cp ( S? '|' S? cp )+ S? ')'
118
+ [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
119
+ [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*'
120
+ | '(' S? '#PCDATA' S? ')'
121
+
122
+
123
+
124
+ == $BL$Ce<j$GCe<jM=Dj$N$J$$$b$N!#(B
125
+
126
+ $B30It<BBN$K4X$9$k$b$NEy!#(B
127
+
128
+ $B$3$l$i$O30It(BDTD$B%5%V%;%C%H$G$J$$$HMQL5$7!#(B
129
+
130
+ [30] extSubset ::= TextDecl? extSubsetDecl
131
+ [31] extSubsetDecl ::= ( markupdecl | conditionalSect | DeclSep)*
132
+ [61] conditionalSect ::= includeSect | ignoreSect
133
+ [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
134
+ [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
135
+ [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
136
+ [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
137
+
138
+ $B$3$l$i$O30It2r@OBP>]<BBN$G$J$$$HMQL5$7!#(B
139
+
140
+ [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
141
+ [78] extParsedEnt ::= TextDecl? content
142
+
143
+ $B$3$l$i$OB0@-CM$NBEEv@-$r8!>Z$7$J$$$J$iMQL5$7!#(B
144
+
145
+ [6] Names ::= Name (S Name)*
146
+ [8] Nmtokens ::= Nmtoken (S Nmtoken)*
147
+
148
+
149
+
150
+
151
+ == $BJ8;z$dL>A0$K4X$9$k$b$N!#(B
152
+
153
+ /[ \t\n\r]+/ $B$H$7$FB>$N@8@.5,B'Fb$KE83+$5$l$k!#(B
154
+ Ruby $B$N(B \s $B$O(B #xC $B$r4^$s$G$7$^$&$N$G87L)$K$O(B S $B$H0lCW$7$J$$$3$H$KCm0U!#(B
155
+
156
+ [3] S ::= (#x20 | #x9 | #xD | #xA)+
157
+
158
+
159
+ $B0J2<$O87L)$K<BAu$9$k$HIi2Y$,$+$+$C$F7y$J$N$G%G%U%)%k%H$G$OL58z!#(B
160
+ $B%*%W%7%g%s$H$7$FA*Br$9$k$3$H$,$G$-$k!#(B
161
+
162
+
163
+ XMLScan::XMLChar::valid_char?
164
+
165
+ [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
166
+ | [#x10000-#x10FFFF]
167
+
168
+ XMLScan::XMLChar::valid_nmtoken?
169
+
170
+ [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':'
171
+ | CombiningChar | Extender
172
+ [7] Nmtoken ::= (NameChar)+
173
+ [84] Letter ::= BaseChar | Ideographic
174
+ [85] BaseChar ::= ...
175
+ [86] Ideographic ::= ...
176
+ [87] CombiningChar ::= ...
177
+ [88] Digit ::= ...
178
+ [89] Extender ::= ...
179
+
180
+ XMLScan::XMLChar::valid_name?
181
+
182
+ [5] Name ::= (Letter | '_' | ':') (NameChar)*
183
+
184
+ XMLScan::XMLChar::valid_pubid?
185
+
186
+ [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9]
187
+ | [-'()+,./:=?;!*#@$_%]
188
+
189
+ XMLScan::XMLChar::valid_versionnum?
190
+
191
+ [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+
192
+
193
+ XMLScan::XMLChar::valid_encname?
194
+
195
+ [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
@@ -0,0 +1,335 @@
1
+ # $Id: contentspec.ry,v 1.2 2003/01/19 22:38:46 katsu Exp $
2
+
3
+ #[46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
4
+ #[47] children ::= (choice | seq) ('?' | '*' | '+')?
5
+ #[48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6
+ #[49] choice ::= '(' S? cp ( S? '|' S? cp )+ S? ')'
7
+ #[50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
8
+ #[51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*'
9
+ # | '(' S? '#PCDATA' S? ')'
10
+ # �����Ǥ�դ�������ǽ�������� ? * + ��ľ���˶�����֤��ʤ���
11
+
12
+
13
+ # + positive closure (������)
14
+ # * kleene closure (����)
15
+ # ?
16
+ # | union (����)
17
+ # , concatenation (Ϣ��)
18
+
19
+
20
+ class ContentSpecParser
21
+
22
+ options no_result_var
23
+
24
+ rule
25
+
26
+ contentspec: 'EMPTY'
27
+ | 'ANY'
28
+ { @result.push :ANY }
29
+ | mixed
30
+ | children
31
+
32
+ mixed: '(' mixedelem ')*'
33
+ { @result.push :* }
34
+ | '(' '#PCDATA' ')'
35
+ { @result.push :PCDATA }
36
+ | '(' '#PCDATA' ')*'
37
+ { @result.push :PCDATA, :- }
38
+
39
+ mixedelem: '#PCDATA' '|' Name
40
+ { @result.push :PCDATA, val[2], :| }
41
+ | mixedelem '|' Name
42
+ { @result.push val[2], :| }
43
+
44
+ children: choice
45
+ | seq
46
+
47
+ choice: '(' choicelist listend
48
+
49
+ choicelist: cp '|' cp
50
+ { @result.push :| }
51
+ | choicelist '|' cp
52
+ { @result.push :| }
53
+
54
+ seq: '(' seqlist listend
55
+
56
+ seqlist: cp
57
+ | seqlist ',' cp
58
+ { @result.push :** }
59
+
60
+ listend: ')'
61
+ | ')?'
62
+ { @result.push :- }
63
+ | ')*'
64
+ { @result.push :* }
65
+ | ')+'
66
+ { @result.push :+ }
67
+
68
+ cp: Name
69
+ { @result.push val[0] }
70
+ | NameQ
71
+ { @result.push val[0], :- }
72
+ | NameA
73
+ { @result.push val[0], :* }
74
+ | NameP
75
+ { @result.push val[0], :+ }
76
+ | choice
77
+ | seq
78
+
79
+ end
80
+
81
+
82
+ ---- inner ----
83
+
84
+ def next_token
85
+ @tokens.shift
86
+ end
87
+
88
+ def parse(src)
89
+ @tokens = []
90
+ first = true
91
+ src.scan(/([^ \t\n\r(|,)?*+]+[?*+]?)|([(|,]|\)[?*+]?)|([^ \t\n\r][\S\s]*)/
92
+ ) { |name,delim,error|
93
+ if name then
94
+ if first and (name == 'EMPTY' or name == 'ANY') then
95
+ @tokens.push [ name, name ]
96
+ elsif name == '#PCDATA' then
97
+ @tokens.push [ name, name ]
98
+ else
99
+ c = name[-1]
100
+ if c == ?? then
101
+ name.chop!
102
+ @tokens.push [ :NameQ, name ]
103
+ elsif c == ?* then
104
+ name.chop!
105
+ @tokens.push [ :NameA, name ]
106
+ elsif c == ?+ then
107
+ name.chop!
108
+ @tokens.push [ :NameP, name ]
109
+ else
110
+ @tokens.push [ :Name, name ]
111
+ end
112
+ end
113
+ elsif delim then
114
+ @tokens.push [ delim, delim ]
115
+ else
116
+ raise error
117
+ end
118
+ }
119
+ @tokens.push [ false, nil ]
120
+ @yydebug = true
121
+ @result = []
122
+ do_parse
123
+ @result
124
+ end
125
+
126
+ ---- footer ----
127
+
128
+
129
+
130
+
131
+ module XMLScan
132
+
133
+ class DTDScanner
134
+
135
+ def parse_error(msg)
136
+ print " #{caller[0]}: ", msg, "\n"
137
+ end
138
+
139
+ ClosureMark = { ?? => :-, ?* => :*, ?+ => :+ }
140
+ SeqDelim = { ?, => :**, ?| => :| }
141
+
142
+ def scan_contentspec(src)
143
+ dst = []
144
+ parenstack = []
145
+ pcdata = false
146
+ parenallow = true
147
+ if src == 'EMPTY' then
148
+ return []
149
+ elsif src == 'ANY' then
150
+ return [:ANY]
151
+ end
152
+ src.scan(
153
+ /([^ \t\n\r(|,)?*+%;]+[?*+]?)|([(|,]|\)[?*+]?)|([^ \t\n\r][\S\s]*)/
154
+ ) { |name,delim,error|
155
+ if name then
156
+ if not parenallow or parenstack.empty? then
157
+ parse_error "parse error at `#{name}'"
158
+ break
159
+ # RECOVERY-01: insert a `(' before Name. Also insert `,(' if needed
160
+ parenstack.push nil if parenstack.empty?
161
+ parenstack[-1] = (:**) unless parenstack.last
162
+ parenstack.push nil
163
+ end
164
+ mark = ClosureMark[name[-1]]
165
+ name.chop! if mark
166
+ if name == '#PCDATA' then
167
+ if mark or not dst.empty? or parenstack.size > 1 then
168
+ parse_error "parse error at `#{name}#{mark&&mark.chr}'"
169
+ break
170
+ dst.push '#PCDATA' # RECOVERY-02: regard as an element type.
171
+ dst.push mark if mark
172
+ mark = parenstack.last
173
+ dst.push mark if mark
174
+ else
175
+ dst.push :PCDATA
176
+ pcdata = true
177
+ parenstack[-1] = :|
178
+ end
179
+ else
180
+ dst.push name
181
+ dst.push mark if mark
182
+ mark = parenstack.last
183
+ dst.push mark if mark
184
+ end
185
+ parenallow = false
186
+ elsif delim then
187
+ mark = delim[1]
188
+ delim = delim[0]
189
+ if delim == ?( then
190
+ if not parenallow or pcdata then
191
+ parse_error "parse error at `('"
192
+ break
193
+ if pcdata then # RECOVERY-03: allow it with limitation.
194
+ parenstack.push :|
195
+ else # RECOVERY-04: insert a `,' before `('.
196
+ parenstack[-1] = (:**) unless parenstack.last
197
+ parenstack.push nil
198
+ parenallow = true
199
+ end
200
+ else
201
+ parenstack.push nil
202
+ end
203
+ elsif delim == ?) then
204
+ if parenallow then
205
+ parse_error "parse error at `)#{mark&&mark.chr}'"
206
+ parenstack.pop ; break
207
+ mark = nil # RECOVERY-05: allow it but ignore any marks.
208
+ parenallow = false
209
+ end
210
+ if parenstack.empty? then
211
+ parse_error "unbalanced `)'"
212
+ break
213
+ # RECOVERY-06: allow it.
214
+ end
215
+ parenstack.pop
216
+ if pcdata then
217
+ if dst.size > 1 then
218
+ unless parenstack.empty? then
219
+ # here is continuation of RECOVERY-03: ignore any marks.
220
+ else
221
+ unless mark == ?* then
222
+ parse_error "parse error at `)#{mark&&mark.chr}'"
223
+ break
224
+ # RECOVERY-07: replace the mark with a `*'.
225
+ end
226
+ dst.push :*
227
+ end
228
+ elsif mark then
229
+ if mark == ?* then
230
+ dst.push :-
231
+ else
232
+ parse_error "parse error at `)#{mark&&mark.chr}'"
233
+ break
234
+ # RECOVERY-08: ignore it.
235
+ end
236
+ end
237
+ else
238
+ mark = ClosureMark[mark]
239
+ dst.push mark if mark
240
+ mark = parenstack.last
241
+ dst.push mark if mark
242
+ end
243
+ else # | or ,
244
+ if parenallow or parenstack.empty? then
245
+ parse_error "parse error at `#{delim.chr}'"
246
+ break
247
+ # RECOVERY-09: ignore it.
248
+ else
249
+ mark = SeqDelim[delim]
250
+ if parenstack.last then
251
+ unless parenstack.last == mark then
252
+ parse_error "parse error at `#{delim.chr}'"
253
+ break
254
+ # RECOVERY-10: regard that it is same as the previous one.
255
+ end
256
+ else
257
+ parenstack[-1] = mark
258
+ end
259
+ parenallow = true
260
+ end
261
+ end
262
+ elsif error then
263
+ parse_error "parse error `#{error}'"
264
+ break
265
+ parenallow = false # RECOVERY-11: ignore all after.
266
+ parenstack.clear
267
+ end
268
+ }
269
+ #parse_error "unexpected termination of content model" if parenallow
270
+ parse_error "unbalanced `('" unless parenstack.empty?
271
+ dst
272
+ end
273
+
274
+ end
275
+
276
+ end
277
+
278
+
279
+
280
+ Examples = [
281
+ "EMPTY",
282
+ "ANY",
283
+ "(a,b,c)",
284
+ "(a,b*,c)",
285
+ "(a,b*,c+)",
286
+ "(a,(b*,c)+)",
287
+ "(a,(b*|(c,e)?)+,d)+",
288
+ "(a,(b,(c,(d,(e)))))",
289
+ "(a,b,c,d,e)",
290
+ "(((((a),b),c),d),e)",
291
+ "(#PCDATA|a|b|c)",
292
+ "(#PCDATA|a)*",
293
+ "(#PCDATA|a|b|c)*",
294
+ "(a|#PCDATA|a|b|c)*",
295
+ "()*",
296
+ "(a,)?",
297
+ "((a,b,),c)?",
298
+ "(a))",
299
+ "((a))",
300
+ "(a)b)",
301
+ "(a(b))",
302
+ "(a)",
303
+ "(a)*",
304
+ "(#PCDATA)",
305
+ "(#PCDATA)*",
306
+ "(#PCDATA)?",
307
+ "(a,(#PCDATA|b|c)*,d)",
308
+ "a*",
309
+ "a|b",
310
+ "EMPTY|b",
311
+ '(a|b,c)',
312
+ '(#PCDATA|(a|b)|c)*',
313
+ '(#PCDATA|a|(b|c))*',
314
+ ',a',
315
+ '(a)(b,c)',
316
+ '(#PCDATA)(a,b)',
317
+ '(a,,b)',
318
+ ]
319
+
320
+ Examples.each { |s|
321
+ p s
322
+ puts
323
+ begin
324
+ print ' ', ContentSpecParser.new.parse(s).inspect, "\n"
325
+ rescue => e
326
+ print " ERROR: #{caller[0]}: ", e.message.strip, " (#{e.class.name})\n"
327
+ end
328
+ puts
329
+ begin
330
+ print ' ', XMLScan::DTDScanner.new.scan_contentspec(s).inspect, "\n"
331
+ rescue => e
332
+ print " ERROR: #{caller[0]}: ", e.message, " (#{e.class.name})\n"
333
+ end
334
+ puts
335
+ }