rgen 0.5.4 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/CHANGELOG +28 -0
  2. data/Rakefile +3 -4
  3. data/lib/ea_support/uml13_ea_metamodel.rb +3 -3
  4. data/lib/ea_support/uml13_ea_to_uml13.rb +33 -2
  5. data/lib/ea_support/uml13_to_uml13_ea.rb +7 -0
  6. data/lib/mmgen/mm_ext/ecore_mmgen_ext.rb +4 -4
  7. data/lib/mmgen/templates/metamodel_generator.tpl +143 -143
  8. data/lib/rgen/ecore/ecore.rb +11 -1
  9. data/lib/rgen/ecore/ecore_interface.rb +47 -0
  10. data/lib/rgen/ecore/ecore_to_ruby.rb +166 -0
  11. data/lib/rgen/ecore/{ecore_transformer.rb → ruby_to_ecore.rb} +11 -11
  12. data/lib/rgen/environment.rb +15 -2
  13. data/lib/rgen/fragment/dump_file_cache.rb +63 -0
  14. data/lib/rgen/fragment/fragmented_model.rb +139 -0
  15. data/lib/rgen/fragment/model_fragment.rb +268 -0
  16. data/lib/rgen/instantiator/abstract_xml_instantiator.rb +44 -72
  17. data/lib/rgen/instantiator/default_xml_instantiator.rb +2 -2
  18. data/lib/rgen/instantiator/ecore_xml_instantiator.rb +16 -1
  19. data/lib/rgen/instantiator/json_instantiator.rb +16 -2
  20. data/lib/rgen/instantiator/nodebased_xml_instantiator.rb +118 -138
  21. data/lib/rgen/instantiator/qualified_name_resolver.rb +5 -1
  22. data/lib/rgen/instantiator/reference_resolver.rb +126 -24
  23. data/lib/rgen/instantiator/xmi11_instantiator.rb +6 -2
  24. data/lib/rgen/metamodel_builder.rb +18 -6
  25. data/lib/rgen/metamodel_builder/builder_extensions.rb +431 -407
  26. data/lib/rgen/metamodel_builder/builder_runtime.rb +8 -8
  27. data/lib/rgen/metamodel_builder/constant_order_helper.rb +4 -4
  28. data/lib/rgen/metamodel_builder/data_types.rb +5 -1
  29. data/lib/rgen/metamodel_builder/intermediate/feature.rb +167 -0
  30. data/lib/rgen/metamodel_builder/module_extension.rb +2 -2
  31. data/lib/rgen/model_builder.rb +10 -5
  32. data/lib/rgen/model_builder/builder_context.rb +17 -1
  33. data/lib/rgen/serializer/opposite_reference_filter.rb +18 -0
  34. data/lib/rgen/serializer/qualified_name_provider.rb +45 -0
  35. data/lib/rgen/template_language/template_container.rb +3 -1
  36. data/lib/rgen/{auto_class_creator.rb → util/auto_class_creator.rb} +6 -1
  37. data/lib/rgen/util/cached_glob.rb +67 -0
  38. data/lib/rgen/util/file_cache_map.rb +104 -0
  39. data/lib/rgen/util/file_change_detector.rb +78 -0
  40. data/lib/rgen/{method_delegation.rb → util/method_delegation.rb} +18 -3
  41. data/lib/rgen/{model_comparator.rb → util/model_comparator.rb} +17 -5
  42. data/lib/rgen/{model_comparator_base.rb → util/model_comparator_base.rb} +6 -1
  43. data/lib/rgen/{model_dumper.rb → util/model_dumper.rb} +6 -1
  44. data/lib/rgen/{name_helper.rb → util/name_helper.rb} +6 -1
  45. data/lib/rgen/util/pattern_matcher.rb +329 -0
  46. data/lib/transformers/uml13_to_ecore.rb +103 -60
  47. data/test/ecore_self_test.rb +43 -42
  48. data/test/json_test.rb +15 -0
  49. data/test/metamodel_builder_test.rb +361 -206
  50. data/test/metamodel_from_ecore_test.rb +45 -0
  51. data/test/metamodel_order_test.rb +10 -4
  52. data/test/metamodel_roundtrip_test.rb +2 -2
  53. data/test/metamodel_roundtrip_test/TestModel_Regenerated.rb +1 -1
  54. data/test/metamodel_roundtrip_test/houseMetamodel_Regenerated.ecore +50 -50
  55. data/test/method_delegation_test.rb +9 -9
  56. data/test/model_builder/ecore_internal.rb +19 -9
  57. data/test/model_builder/serializer_test.rb +1 -1
  58. data/test/reference_resolver_test.rb +79 -12
  59. data/test/rgen_test.rb +2 -0
  60. data/test/template_language_test.rb +7 -0
  61. data/test/template_language_test/templates/callback_indent_test/a.tpl +12 -0
  62. data/test/template_language_test/templates/callback_indent_test/b.tpl +5 -0
  63. data/test/testmodel/ea_testmodel_regenerated.xml +588 -583
  64. data/test/transformer_test.rb +3 -3
  65. data/test/util/file_cache_map_test.rb +91 -0
  66. data/test/util/file_cache_map_test/testdir/fileA +1 -0
  67. data/test/util_test.rb +4 -0
  68. data/test/xml_instantiator_test.rb +139 -135
  69. metadata +49 -104
  70. data/lib/rgen/ecore/ecore_instantiator.rb +0 -31
  71. data/lib/rgen/metamodel_builder/metamodel_description.rb +0 -232
  72. data/redist/xmlscan/ChangeLog +0 -1301
  73. data/redist/xmlscan/README +0 -34
  74. data/redist/xmlscan/THANKS +0 -11
  75. data/redist/xmlscan/doc/changes.html +0 -74
  76. data/redist/xmlscan/doc/changes.rd +0 -80
  77. data/redist/xmlscan/doc/en/conformance.html +0 -136
  78. data/redist/xmlscan/doc/en/conformance.rd +0 -152
  79. data/redist/xmlscan/doc/en/manual.html +0 -356
  80. data/redist/xmlscan/doc/en/manual.rd +0 -402
  81. data/redist/xmlscan/doc/ja/conformance.ja.html +0 -118
  82. data/redist/xmlscan/doc/ja/conformance.ja.rd +0 -134
  83. data/redist/xmlscan/doc/ja/manual.ja.html +0 -325
  84. data/redist/xmlscan/doc/ja/manual.ja.rd +0 -370
  85. data/redist/xmlscan/doc/src/Makefile +0 -41
  86. data/redist/xmlscan/doc/src/conformance.rd.src +0 -256
  87. data/redist/xmlscan/doc/src/langsplit.rb +0 -110
  88. data/redist/xmlscan/doc/src/manual.rd.src +0 -614
  89. data/redist/xmlscan/install.rb +0 -41
  90. data/redist/xmlscan/lib/xmlscan/encoding.rb +0 -311
  91. data/redist/xmlscan/lib/xmlscan/htmlscan.rb +0 -289
  92. data/redist/xmlscan/lib/xmlscan/namespace.rb +0 -352
  93. data/redist/xmlscan/lib/xmlscan/parser.rb +0 -299
  94. data/redist/xmlscan/lib/xmlscan/scanner.rb +0 -1109
  95. data/redist/xmlscan/lib/xmlscan/version.rb +0 -22
  96. data/redist/xmlscan/lib/xmlscan/visitor.rb +0 -158
  97. data/redist/xmlscan/lib/xmlscan/xmlchar.rb +0 -441
  98. data/redist/xmlscan/memo/CONFORMANCE +0 -1249
  99. data/redist/xmlscan/memo/PRODUCTIONS +0 -195
  100. data/redist/xmlscan/memo/contentspec.ry +0 -335
  101. data/redist/xmlscan/samples/chibixml.rb +0 -105
  102. data/redist/xmlscan/samples/getxmlchar.rb +0 -122
  103. data/redist/xmlscan/samples/rexml.rb +0 -159
  104. data/redist/xmlscan/samples/xmlbench.rb +0 -88
  105. data/redist/xmlscan/samples/xmlbench/parser/chibixml.rb +0 -22
  106. data/redist/xmlscan/samples/xmlbench/parser/nqxml.rb +0 -29
  107. data/redist/xmlscan/samples/xmlbench/parser/rexml.rb +0 -62
  108. data/redist/xmlscan/samples/xmlbench/parser/xmlparser.rb +0 -22
  109. data/redist/xmlscan/samples/xmlbench/parser/xmlscan-0.0.10.rb +0 -62
  110. data/redist/xmlscan/samples/xmlbench/parser/xmlscan-chibixml.rb +0 -22
  111. data/redist/xmlscan/samples/xmlbench/parser/xmlscan-rexml.rb +0 -22
  112. data/redist/xmlscan/samples/xmlbench/parser/xmlscan.rb +0 -99
  113. data/redist/xmlscan/samples/xmlbench/xmlbench-lib.rb +0 -116
  114. data/redist/xmlscan/samples/xmlconftest.rb +0 -200
  115. data/redist/xmlscan/test.rb +0 -7
  116. data/redist/xmlscan/tests/deftestcase.rb +0 -73
  117. data/redist/xmlscan/tests/runtest.rb +0 -47
  118. data/redist/xmlscan/tests/testall.rb +0 -14
  119. data/redist/xmlscan/tests/testencoding.rb +0 -438
  120. data/redist/xmlscan/tests/testhtmlscan.rb +0 -752
  121. data/redist/xmlscan/tests/testnamespace.rb +0 -457
  122. data/redist/xmlscan/tests/testparser.rb +0 -591
  123. data/redist/xmlscan/tests/testscanner.rb +0 -1749
  124. data/redist/xmlscan/tests/testxmlchar.rb +0 -143
  125. data/redist/xmlscan/tests/visitor.rb +0 -34
@@ -1,195 +0,0 @@
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._] | '-')*
@@ -1,335 +0,0 @@
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
- }