rgen 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +20 -1
- data/MIT-LICENSE +1 -1
- data/README +12 -9
- data/lib/instantiators/ea_instantiator.rb +36 -0
- data/lib/metamodels/uml13_metamodel.rb +559 -0
- data/lib/metamodels/uml13_metamodel_ext.rb +26 -0
- data/lib/mmgen/metamodel_generator.rb +5 -5
- data/lib/mmgen/mm_ext/ecore_ext.rb +95 -0
- data/lib/mmgen/mmgen.rb +6 -4
- data/lib/mmgen/templates/annotations.tpl +37 -0
- data/lib/mmgen/templates/metamodel_generator.tpl +171 -0
- data/lib/rgen/ecore/ecore.rb +190 -0
- data/lib/rgen/ecore/ecore_instantiator.rb +25 -0
- data/lib/rgen/ecore/ecore_transformer.rb +85 -0
- data/lib/rgen/environment.rb +9 -24
- data/lib/rgen/find_helper.rb +68 -0
- data/lib/rgen/{instantiator.rb → instantiator/abstract_instantiator.rb} +6 -2
- data/lib/rgen/instantiator/abstract_xml_instantiator.rb +59 -0
- data/lib/rgen/instantiator/default_xml_instantiator.rb +117 -0
- data/lib/rgen/instantiator/ecore_xml_instantiator.rb +144 -0
- data/lib/rgen/instantiator/nodebased_xml_instantiator.rb +157 -0
- data/lib/rgen/instantiator/xmi11_instantiator.rb +164 -0
- data/lib/rgen/metamodel_builder.rb +103 -9
- data/lib/rgen/metamodel_builder/build_helper.rb +26 -4
- data/lib/rgen/metamodel_builder/builder_extensions.rb +285 -88
- data/lib/rgen/metamodel_builder/builder_runtime.rb +7 -1
- data/lib/rgen/metamodel_builder/data_types.rb +67 -0
- data/lib/rgen/metamodel_builder/intermediate/annotation.rb +30 -0
- data/lib/rgen/metamodel_builder/metamodel_description.rb +232 -0
- data/lib/rgen/metamodel_builder/mm_multiple.rb +23 -0
- data/lib/rgen/metamodel_builder/module_extension.rb +33 -0
- data/lib/rgen/model_comparator.rb +56 -0
- data/lib/rgen/model_dumper.rb +5 -5
- data/lib/rgen/name_helper.rb +17 -1
- data/lib/rgen/template_language.rb +148 -28
- data/lib/rgen/template_language/directory_template_container.rb +56 -38
- data/lib/rgen/template_language/output_handler.rb +93 -77
- data/lib/rgen/template_language/template_container.rb +186 -143
- data/lib/rgen/transformer.rb +19 -14
- data/lib/transformers/uml13_to_ecore.rb +75 -0
- data/redist/xmlscan/ChangeLog +1301 -0
- data/redist/xmlscan/README +34 -0
- data/redist/xmlscan/THANKS +11 -0
- data/redist/xmlscan/doc/changes.html +74 -0
- data/redist/xmlscan/doc/changes.rd +80 -0
- data/redist/xmlscan/doc/en/conformance.html +136 -0
- data/redist/xmlscan/doc/en/conformance.rd +152 -0
- data/redist/xmlscan/doc/en/manual.html +356 -0
- data/redist/xmlscan/doc/en/manual.rd +402 -0
- data/redist/xmlscan/doc/ja/conformance.ja.html +118 -0
- data/redist/xmlscan/doc/ja/conformance.ja.rd +134 -0
- data/redist/xmlscan/doc/ja/manual.ja.html +325 -0
- data/redist/xmlscan/doc/ja/manual.ja.rd +370 -0
- data/redist/xmlscan/doc/src/Makefile +41 -0
- data/redist/xmlscan/doc/src/conformance.rd.src +256 -0
- data/redist/xmlscan/doc/src/langsplit.rb +110 -0
- data/redist/xmlscan/doc/src/manual.rd.src +614 -0
- data/redist/xmlscan/install.rb +41 -0
- data/redist/xmlscan/lib/xmlscan/encoding.rb +311 -0
- data/redist/xmlscan/lib/xmlscan/htmlscan.rb +289 -0
- data/redist/xmlscan/lib/xmlscan/namespace.rb +352 -0
- data/redist/xmlscan/lib/xmlscan/parser.rb +299 -0
- data/redist/xmlscan/lib/xmlscan/scanner.rb +1109 -0
- data/redist/xmlscan/lib/xmlscan/version.rb +22 -0
- data/redist/xmlscan/lib/xmlscan/visitor.rb +158 -0
- data/redist/xmlscan/lib/xmlscan/xmlchar.rb +441 -0
- data/redist/xmlscan/memo/CONFORMANCE +1249 -0
- data/redist/xmlscan/memo/PRODUCTIONS +195 -0
- data/redist/xmlscan/memo/contentspec.ry +335 -0
- data/redist/xmlscan/samples/chibixml.rb +105 -0
- data/redist/xmlscan/samples/getxmlchar.rb +122 -0
- data/redist/xmlscan/samples/rexml.rb +159 -0
- data/redist/xmlscan/samples/xmlbench.rb +88 -0
- data/redist/xmlscan/samples/xmlbench/parser/chibixml.rb +22 -0
- data/redist/xmlscan/samples/xmlbench/parser/nqxml.rb +29 -0
- data/redist/xmlscan/samples/xmlbench/parser/rexml.rb +62 -0
- data/redist/xmlscan/samples/xmlbench/parser/xmlparser.rb +22 -0
- data/redist/xmlscan/samples/xmlbench/parser/xmlscan-0.0.10.rb +62 -0
- data/redist/xmlscan/samples/xmlbench/parser/xmlscan-chibixml.rb +22 -0
- data/redist/xmlscan/samples/xmlbench/parser/xmlscan-rexml.rb +22 -0
- data/redist/xmlscan/samples/xmlbench/parser/xmlscan.rb +99 -0
- data/redist/xmlscan/samples/xmlbench/xmlbench-lib.rb +116 -0
- data/redist/xmlscan/samples/xmlconftest.rb +200 -0
- data/redist/xmlscan/test.rb +7 -0
- data/redist/xmlscan/tests/deftestcase.rb +73 -0
- data/redist/xmlscan/tests/runtest.rb +47 -0
- data/redist/xmlscan/tests/testall.rb +14 -0
- data/redist/xmlscan/tests/testencoding.rb +438 -0
- data/redist/xmlscan/tests/testhtmlscan.rb +752 -0
- data/redist/xmlscan/tests/testnamespace.rb +457 -0
- data/redist/xmlscan/tests/testparser.rb +591 -0
- data/redist/xmlscan/tests/testscanner.rb +1749 -0
- data/redist/xmlscan/tests/testxmlchar.rb +143 -0
- data/redist/xmlscan/tests/visitor.rb +34 -0
- data/test/array_extensions_test.rb +2 -2
- data/test/ea_instantiator_test.rb +41 -0
- data/test/ecore_self_test.rb +53 -0
- data/test/environment_test.rb +11 -6
- data/test/metamodel_builder_test.rb +404 -245
- data/test/metamodel_roundtrip_test.rb +52 -0
- data/test/metamodel_roundtrip_test/TestModel.rb +65 -0
- data/test/metamodel_roundtrip_test/TestModel_Regenerated.rb +64 -0
- data/test/metamodel_roundtrip_test/houseMetamodel.ecore +32 -0
- data/test/metamodel_roundtrip_test/houseMetamodel_from_ecore.rb +39 -0
- data/test/rgen_test.rb +3 -3
- data/test/template_language_test.rb +65 -39
- data/test/template_language_test/expected_result.txt +24 -3
- data/test/template_language_test/templates/code/array.tpl +11 -0
- data/test/template_language_test/templates/content/author.tpl +7 -0
- data/test/template_language_test/templates/content/chapter.tpl +1 -1
- data/test/template_language_test/templates/root.tpl +17 -8
- data/test/template_language_test/testout.txt +24 -3
- data/test/testmodel/class_model_checker.rb +119 -0
- data/test/{xmi_instantiator_test/testmodel.eap → testmodel/ea_testmodel.eap} +0 -0
- data/test/{xmi_instantiator_test/testmodel.xml → testmodel/ea_testmodel.xml} +81 -14
- data/test/testmodel/ea_testmodel_partial.xml +317 -0
- data/test/testmodel/ecore_model_checker.rb +101 -0
- data/test/testmodel/manual_testmodel.xml +22 -0
- data/test/testmodel/object_model_checker.rb +67 -0
- data/test/transformer_test.rb +18 -10
- data/test/xml_instantiator_test.rb +81 -8
- data/test/xml_instantiator_test/simple_ecore_model_checker.rb +94 -0
- data/test/xml_instantiator_test/simple_xmi_ecore_instantiator.rb +53 -0
- data/test/xml_instantiator_test/simple_xmi_metamodel.rb +49 -0
- data/test/xml_instantiator_test/simple_xmi_to_ecore.rb +75 -0
- metadata +126 -28
- data/lib/ea/xmi_class_instantiator.rb +0 -46
- data/lib/ea/xmi_helper.rb +0 -26
- data/lib/ea/xmi_metamodel.rb +0 -34
- data/lib/ea/xmi_object_instantiator.rb +0 -46
- data/lib/ea/xmi_to_classmodel.rb +0 -78
- data/lib/ea/xmi_to_objectmodel.rb +0 -92
- data/lib/mmgen/mm_ext/uml_classmodel_ext.rb +0 -71
- data/lib/mmgen/templates/uml_classmodel.tpl +0 -63
- data/lib/rgen/xml_instantiator.rb +0 -132
- data/lib/uml/objectmodel_instantiator.rb +0 -53
- data/lib/uml/uml_classmodel.rb +0 -92
- data/lib/uml/uml_objectmodel.rb +0 -65
- data/test/metamodel_generator_test.rb +0 -44
- data/test/metamodel_generator_test/TestModel.rb +0 -40
- data/test/metamodel_generator_test/expected_result.txt +0 -40
- data/test/xmi_class_instantiator_test.rb +0 -24
- data/test/xmi_instantiator_test/class_model_checker.rb +0 -97
- data/test/xmi_object_instantiator_test.rb +0 -65
- 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
|
+
}
|