1*0Sstevel@tonic-gate // Copyright (c) 1994 James Clark
2*0Sstevel@tonic-gate // See the file COPYING for copying permission.
3*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
4*0Sstevel@tonic-gate
5*0Sstevel@tonic-gate #include "splib.h"
6*0Sstevel@tonic-gate #include "Parser.h"
7*0Sstevel@tonic-gate #include "Param.h"
8*0Sstevel@tonic-gate #include "Group.h"
9*0Sstevel@tonic-gate #include "Markup.h"
10*0Sstevel@tonic-gate #include "ParserMessages.h"
11*0Sstevel@tonic-gate #include "MessageArg.h"
12*0Sstevel@tonic-gate #include "TokenMessageArg.h"
13*0Sstevel@tonic-gate #include "token.h"
14*0Sstevel@tonic-gate #include "macros.h"
15*0Sstevel@tonic-gate
16*0Sstevel@tonic-gate #ifdef SP_NAMESPACE
17*0Sstevel@tonic-gate namespace SP_NAMESPACE {
18*0Sstevel@tonic-gate #endif
19*0Sstevel@tonic-gate
parseParam(const AllowedParams & allow,unsigned declInputLevel,Param & parm)20*0Sstevel@tonic-gate Boolean Parser::parseParam(const AllowedParams &allow,
21*0Sstevel@tonic-gate unsigned declInputLevel,
22*0Sstevel@tonic-gate Param &parm)
23*0Sstevel@tonic-gate {
24*0Sstevel@tonic-gate for (;;) {
25*0Sstevel@tonic-gate Token token = getToken(allow.mainMode());
26*0Sstevel@tonic-gate switch (token) {
27*0Sstevel@tonic-gate case tokenUnrecognized:
28*0Sstevel@tonic-gate if (reportNonSgmlCharacter())
29*0Sstevel@tonic-gate break;
30*0Sstevel@tonic-gate {
31*0Sstevel@tonic-gate message(ParserMessages::markupDeclarationCharacter,
32*0Sstevel@tonic-gate StringMessageArg(currentToken()),
33*0Sstevel@tonic-gate AllowedParamsMessageArg(allow, syntaxPointer()));
34*0Sstevel@tonic-gate }
35*0Sstevel@tonic-gate return 0;
36*0Sstevel@tonic-gate case tokenEe:
37*0Sstevel@tonic-gate if (inputLevel() <= declInputLevel) {
38*0Sstevel@tonic-gate message(ParserMessages::declarationLevel);
39*0Sstevel@tonic-gate return 0;
40*0Sstevel@tonic-gate }
41*0Sstevel@tonic-gate if (currentMarkup())
42*0Sstevel@tonic-gate currentMarkup()->addEntityEnd();
43*0Sstevel@tonic-gate popInputStack();
44*0Sstevel@tonic-gate break;
45*0Sstevel@tonic-gate case tokenCom:
46*0Sstevel@tonic-gate if (!parseComment(comMode))
47*0Sstevel@tonic-gate return 0;
48*0Sstevel@tonic-gate if (options().warnPsComment)
49*0Sstevel@tonic-gate message(ParserMessages::psComment);
50*0Sstevel@tonic-gate break;
51*0Sstevel@tonic-gate case tokenDso:
52*0Sstevel@tonic-gate if (!allow.dso()) {
53*0Sstevel@tonic-gate paramInvalidToken(tokenDso, allow);
54*0Sstevel@tonic-gate return 0;
55*0Sstevel@tonic-gate }
56*0Sstevel@tonic-gate if (currentMarkup())
57*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dDSO);
58*0Sstevel@tonic-gate parm.type = Param::dso;
59*0Sstevel@tonic-gate return 1;
60*0Sstevel@tonic-gate case tokenGrpo:
61*0Sstevel@tonic-gate if (currentMarkup())
62*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dGRPO);
63*0Sstevel@tonic-gate switch (allow.group()) {
64*0Sstevel@tonic-gate case Param::invalid:
65*0Sstevel@tonic-gate paramInvalidToken(tokenGrpo, allow);
66*0Sstevel@tonic-gate return 0;
67*0Sstevel@tonic-gate case Param::modelGroup:
68*0Sstevel@tonic-gate {
69*0Sstevel@tonic-gate ModelGroup *group;
70*0Sstevel@tonic-gate if (!parseModelGroup(1, declInputLevel, group, grpsufMode))
71*0Sstevel@tonic-gate return 0;
72*0Sstevel@tonic-gate parm.type = Param::modelGroup;
73*0Sstevel@tonic-gate parm.modelGroupPtr = group;
74*0Sstevel@tonic-gate }
75*0Sstevel@tonic-gate break;
76*0Sstevel@tonic-gate case Param::nameGroup:
77*0Sstevel@tonic-gate if (!parseNameGroup(declInputLevel, parm))
78*0Sstevel@tonic-gate return 0;
79*0Sstevel@tonic-gate break;
80*0Sstevel@tonic-gate case Param::nameTokenGroup:
81*0Sstevel@tonic-gate if (!parseNameTokenGroup(declInputLevel, parm))
82*0Sstevel@tonic-gate return 0;
83*0Sstevel@tonic-gate break;
84*0Sstevel@tonic-gate default:
85*0Sstevel@tonic-gate CANNOT_HAPPEN();
86*0Sstevel@tonic-gate }
87*0Sstevel@tonic-gate parm.type = allow.group();
88*0Sstevel@tonic-gate return 1;
89*0Sstevel@tonic-gate case tokenLita:
90*0Sstevel@tonic-gate case tokenLit:
91*0Sstevel@tonic-gate parm.type = allow.literal();
92*0Sstevel@tonic-gate parm.lita = token == tokenLita;
93*0Sstevel@tonic-gate switch (allow.literal()) {
94*0Sstevel@tonic-gate case Param::invalid:
95*0Sstevel@tonic-gate paramInvalidToken(token, allow);
96*0Sstevel@tonic-gate return 0;
97*0Sstevel@tonic-gate case Param::minimumLiteral:
98*0Sstevel@tonic-gate if (!parseMinimumLiteral(parm.lita, parm.literalText))
99*0Sstevel@tonic-gate return 0;
100*0Sstevel@tonic-gate break;
101*0Sstevel@tonic-gate case Param::attributeValueLiteral:
102*0Sstevel@tonic-gate if (!parseAttributeValueLiteral(parm.lita, parm.literalText))
103*0Sstevel@tonic-gate return 0;
104*0Sstevel@tonic-gate break;
105*0Sstevel@tonic-gate case Param::tokenizedAttributeValueLiteral:
106*0Sstevel@tonic-gate if (!parseTokenizedAttributeValueLiteral(parm.lita, parm.literalText))
107*0Sstevel@tonic-gate return 0;
108*0Sstevel@tonic-gate break;
109*0Sstevel@tonic-gate case Param::systemIdentifier:
110*0Sstevel@tonic-gate if (!parseSystemIdentifier(parm.lita, parm.literalText))
111*0Sstevel@tonic-gate return 0;
112*0Sstevel@tonic-gate break;
113*0Sstevel@tonic-gate case Param::paramLiteral:
114*0Sstevel@tonic-gate if (!parseParameterLiteral(parm.lita, parm.literalText))
115*0Sstevel@tonic-gate return 0;
116*0Sstevel@tonic-gate break;
117*0Sstevel@tonic-gate }
118*0Sstevel@tonic-gate if (currentMarkup())
119*0Sstevel@tonic-gate currentMarkup()->addLiteral(parm.literalText);
120*0Sstevel@tonic-gate return 1;
121*0Sstevel@tonic-gate case tokenMdc:
122*0Sstevel@tonic-gate if (!allow.mdc()) {
123*0Sstevel@tonic-gate paramInvalidToken(tokenMdc, allow);
124*0Sstevel@tonic-gate return 0;
125*0Sstevel@tonic-gate }
126*0Sstevel@tonic-gate if (inputLevel() > declInputLevel)
127*0Sstevel@tonic-gate message(ParserMessages::parameterEntityNotEnded);
128*0Sstevel@tonic-gate if (currentMarkup())
129*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dMDC);
130*0Sstevel@tonic-gate parm.type = Param::mdc;
131*0Sstevel@tonic-gate return 1;
132*0Sstevel@tonic-gate case tokenMinus:
133*0Sstevel@tonic-gate parm.type = Param::minus;
134*0Sstevel@tonic-gate if (currentMarkup())
135*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dMINUS);
136*0Sstevel@tonic-gate return 1;
137*0Sstevel@tonic-gate case tokenMinusGrpo:
138*0Sstevel@tonic-gate if (!allow.exclusions()) {
139*0Sstevel@tonic-gate paramInvalidToken(tokenMinusGrpo, allow);
140*0Sstevel@tonic-gate return 0;
141*0Sstevel@tonic-gate }
142*0Sstevel@tonic-gate if (currentMarkup()) {
143*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dMINUS);
144*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dGRPO);
145*0Sstevel@tonic-gate }
146*0Sstevel@tonic-gate parm.type = Param::exclusions;
147*0Sstevel@tonic-gate return parseElementNameGroup(declInputLevel, parm);
148*0Sstevel@tonic-gate case tokenPero:
149*0Sstevel@tonic-gate parm.type = Param::pero;
150*0Sstevel@tonic-gate if (currentMarkup())
151*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dPERO);
152*0Sstevel@tonic-gate return 1;
153*0Sstevel@tonic-gate case tokenPeroGrpo:
154*0Sstevel@tonic-gate if (!inInstance())
155*0Sstevel@tonic-gate message(ParserMessages::peroGrpoProlog);
156*0Sstevel@tonic-gate // fall through
157*0Sstevel@tonic-gate case tokenPeroNameStart:
158*0Sstevel@tonic-gate {
159*0Sstevel@tonic-gate if (inInstance()) {
160*0Sstevel@tonic-gate if (options().warnInstanceParamEntityRef)
161*0Sstevel@tonic-gate message(ParserMessages::instanceParamEntityRef);
162*0Sstevel@tonic-gate }
163*0Sstevel@tonic-gate else {
164*0Sstevel@tonic-gate if (options().warnInternalSubsetPsParamEntityRef && inputLevel() == 1)
165*0Sstevel@tonic-gate message(ParserMessages::internalSubsetPsParamEntityRef);
166*0Sstevel@tonic-gate }
167*0Sstevel@tonic-gate ConstPtr<Entity> entity;
168*0Sstevel@tonic-gate Ptr<EntityOrigin> origin;
169*0Sstevel@tonic-gate if (!parseEntityReference(1, token == tokenPeroGrpo, entity, origin))
170*0Sstevel@tonic-gate return 0;
171*0Sstevel@tonic-gate if (!entity.isNull())
172*0Sstevel@tonic-gate entity->declReference(*this, origin);
173*0Sstevel@tonic-gate }
174*0Sstevel@tonic-gate break;
175*0Sstevel@tonic-gate case tokenPlusGrpo:
176*0Sstevel@tonic-gate if (!allow.inclusions()) {
177*0Sstevel@tonic-gate paramInvalidToken(tokenPlusGrpo, allow);
178*0Sstevel@tonic-gate return 0;
179*0Sstevel@tonic-gate }
180*0Sstevel@tonic-gate if (currentMarkup()) {
181*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dPLUS);
182*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dGRPO);
183*0Sstevel@tonic-gate }
184*0Sstevel@tonic-gate parm.type = Param::inclusions;
185*0Sstevel@tonic-gate return parseElementNameGroup(declInputLevel, parm);
186*0Sstevel@tonic-gate case tokenRni:
187*0Sstevel@tonic-gate if (!allow.rni()) {
188*0Sstevel@tonic-gate paramInvalidToken(tokenRni, allow);
189*0Sstevel@tonic-gate return 0;
190*0Sstevel@tonic-gate }
191*0Sstevel@tonic-gate return parseIndicatedReservedName(allow, parm);
192*0Sstevel@tonic-gate case tokenS:
193*0Sstevel@tonic-gate if (currentMarkup())
194*0Sstevel@tonic-gate currentMarkup()->addS(currentChar());
195*0Sstevel@tonic-gate break;
196*0Sstevel@tonic-gate case tokenNameStart:
197*0Sstevel@tonic-gate switch (allow.nameStart()) {
198*0Sstevel@tonic-gate case Param::invalid:
199*0Sstevel@tonic-gate paramInvalidToken(tokenNameStart, allow);
200*0Sstevel@tonic-gate return 0;
201*0Sstevel@tonic-gate case Param::reservedName:
202*0Sstevel@tonic-gate return parseReservedName(allow, parm);
203*0Sstevel@tonic-gate case Param::name:
204*0Sstevel@tonic-gate extendNameToken(syntax().namelen(), ParserMessages::nameLength);
205*0Sstevel@tonic-gate parm.type = Param::name;
206*0Sstevel@tonic-gate getCurrentToken(syntax().generalSubstTable(), parm.token);
207*0Sstevel@tonic-gate if (currentMarkup())
208*0Sstevel@tonic-gate currentMarkup()->addName(currentInput());
209*0Sstevel@tonic-gate return 1;
210*0Sstevel@tonic-gate case Param::entityName:
211*0Sstevel@tonic-gate extendNameToken(syntax().namelen(), ParserMessages::nameLength);
212*0Sstevel@tonic-gate parm.type = Param::entityName;
213*0Sstevel@tonic-gate getCurrentToken(syntax().entitySubstTable(), parm.token);
214*0Sstevel@tonic-gate if (currentMarkup())
215*0Sstevel@tonic-gate currentMarkup()->addName(currentInput());
216*0Sstevel@tonic-gate return 1;
217*0Sstevel@tonic-gate case Param::paramEntityName:
218*0Sstevel@tonic-gate extendNameToken(syntax().penamelen(),
219*0Sstevel@tonic-gate ParserMessages::parameterEntityNameLength);
220*0Sstevel@tonic-gate parm.type = Param::paramEntityName;
221*0Sstevel@tonic-gate getCurrentToken(syntax().entitySubstTable(), parm.token);
222*0Sstevel@tonic-gate if (currentMarkup())
223*0Sstevel@tonic-gate currentMarkup()->addName(currentInput());
224*0Sstevel@tonic-gate return 1;
225*0Sstevel@tonic-gate case Param::attributeValue:
226*0Sstevel@tonic-gate return parseAttributeValueParam(parm);
227*0Sstevel@tonic-gate }
228*0Sstevel@tonic-gate break;
229*0Sstevel@tonic-gate case tokenDigit:
230*0Sstevel@tonic-gate switch (allow.digit()) {
231*0Sstevel@tonic-gate case Param::invalid:
232*0Sstevel@tonic-gate paramInvalidToken(tokenDigit, allow);
233*0Sstevel@tonic-gate return 0;
234*0Sstevel@tonic-gate case Param::number:
235*0Sstevel@tonic-gate extendNumber(syntax().namelen(), ParserMessages::numberLength);
236*0Sstevel@tonic-gate parm.type = Param::number;
237*0Sstevel@tonic-gate getCurrentToken(parm.token);
238*0Sstevel@tonic-gate if (currentMarkup())
239*0Sstevel@tonic-gate currentMarkup()->addNumber(currentInput());
240*0Sstevel@tonic-gate return 1;
241*0Sstevel@tonic-gate case Param::attributeValue:
242*0Sstevel@tonic-gate return parseAttributeValueParam(parm);
243*0Sstevel@tonic-gate }
244*0Sstevel@tonic-gate break;
245*0Sstevel@tonic-gate case tokenLcUcNmchar:
246*0Sstevel@tonic-gate switch (allow.nmchar()) {
247*0Sstevel@tonic-gate case Param::invalid:
248*0Sstevel@tonic-gate paramInvalidToken(tokenLcUcNmchar, allow);
249*0Sstevel@tonic-gate return 0;
250*0Sstevel@tonic-gate case Param::attributeValue:
251*0Sstevel@tonic-gate return parseAttributeValueParam(parm);
252*0Sstevel@tonic-gate }
253*0Sstevel@tonic-gate break;
254*0Sstevel@tonic-gate default:
255*0Sstevel@tonic-gate CANNOT_HAPPEN();
256*0Sstevel@tonic-gate }
257*0Sstevel@tonic-gate }
258*0Sstevel@tonic-gate }
259*0Sstevel@tonic-gate
paramInvalidToken(Token token,const AllowedParams & allow)260*0Sstevel@tonic-gate void Parser::paramInvalidToken(Token token, const AllowedParams &allow)
261*0Sstevel@tonic-gate {
262*0Sstevel@tonic-gate message(ParserMessages::paramInvalidToken,
263*0Sstevel@tonic-gate TokenMessageArg(token, allow.mainMode(),
264*0Sstevel@tonic-gate syntaxPointer(), sdPointer()),
265*0Sstevel@tonic-gate AllowedParamsMessageArg(allow, syntaxPointer()));
266*0Sstevel@tonic-gate }
267*0Sstevel@tonic-gate
parseGroupToken(const AllowedGroupTokens & allow,unsigned nestingLevel,unsigned declInputLevel,unsigned groupInputLevel,GroupToken & gt)268*0Sstevel@tonic-gate Boolean Parser::parseGroupToken(const AllowedGroupTokens &allow,
269*0Sstevel@tonic-gate unsigned nestingLevel,
270*0Sstevel@tonic-gate unsigned declInputLevel,
271*0Sstevel@tonic-gate unsigned groupInputLevel,
272*0Sstevel@tonic-gate GroupToken >)
273*0Sstevel@tonic-gate {
274*0Sstevel@tonic-gate for (;;) {
275*0Sstevel@tonic-gate Token token = getToken(grpMode);
276*0Sstevel@tonic-gate switch (token) {
277*0Sstevel@tonic-gate case tokenEe:
278*0Sstevel@tonic-gate if (inputLevel() <= groupInputLevel) {
279*0Sstevel@tonic-gate message(ParserMessages::groupLevel);
280*0Sstevel@tonic-gate if (inputLevel() <= declInputLevel)
281*0Sstevel@tonic-gate return 0;
282*0Sstevel@tonic-gate }
283*0Sstevel@tonic-gate else if (!sd().www())
284*0Sstevel@tonic-gate message(ParserMessages::groupEntityEnd);
285*0Sstevel@tonic-gate if (currentMarkup())
286*0Sstevel@tonic-gate currentMarkup()->addEntityEnd();
287*0Sstevel@tonic-gate popInputStack();
288*0Sstevel@tonic-gate break;
289*0Sstevel@tonic-gate case tokenPeroGrpo:
290*0Sstevel@tonic-gate if (!inInstance())
291*0Sstevel@tonic-gate message(ParserMessages::peroGrpoProlog);
292*0Sstevel@tonic-gate // fall through
293*0Sstevel@tonic-gate case tokenPeroNameStart:
294*0Sstevel@tonic-gate {
295*0Sstevel@tonic-gate if (options().warnInternalSubsetTsParamEntityRef && inputLevel() == 1)
296*0Sstevel@tonic-gate message(ParserMessages::internalSubsetTsParamEntityRef);
297*0Sstevel@tonic-gate ConstPtr<Entity> entity;
298*0Sstevel@tonic-gate Ptr<EntityOrigin> origin;
299*0Sstevel@tonic-gate if (!parseEntityReference(1, token == tokenPeroGrpo, entity, origin))
300*0Sstevel@tonic-gate return 0;
301*0Sstevel@tonic-gate if (!entity.isNull())
302*0Sstevel@tonic-gate entity->declReference(*this, origin);
303*0Sstevel@tonic-gate }
304*0Sstevel@tonic-gate break;
305*0Sstevel@tonic-gate case tokenUnrecognized:
306*0Sstevel@tonic-gate if (reportNonSgmlCharacter())
307*0Sstevel@tonic-gate break;
308*0Sstevel@tonic-gate {
309*0Sstevel@tonic-gate message(ParserMessages::groupCharacter,
310*0Sstevel@tonic-gate StringMessageArg(currentToken()),
311*0Sstevel@tonic-gate AllowedGroupTokensMessageArg(allow, syntaxPointer()));
312*0Sstevel@tonic-gate }
313*0Sstevel@tonic-gate return 0;
314*0Sstevel@tonic-gate case tokenDtgo:
315*0Sstevel@tonic-gate if (!allow.groupToken(GroupToken::dataTagGroup)) {
316*0Sstevel@tonic-gate groupTokenInvalidToken(tokenDtgo, allow);
317*0Sstevel@tonic-gate return 0;
318*0Sstevel@tonic-gate }
319*0Sstevel@tonic-gate if (sd().datatag())
320*0Sstevel@tonic-gate message(ParserMessages::datatagNotImplemented);
321*0Sstevel@tonic-gate if (currentMarkup())
322*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dDTGO);
323*0Sstevel@tonic-gate return parseDataTagGroup(nestingLevel + 1, declInputLevel, gt);
324*0Sstevel@tonic-gate case tokenGrpo:
325*0Sstevel@tonic-gate if (currentMarkup())
326*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dGRPO);
327*0Sstevel@tonic-gate switch (allow.group()) {
328*0Sstevel@tonic-gate case GroupToken::modelGroup:
329*0Sstevel@tonic-gate {
330*0Sstevel@tonic-gate ModelGroup *modelGroup;
331*0Sstevel@tonic-gate if (!parseModelGroup(nestingLevel + 1, declInputLevel, modelGroup,
332*0Sstevel@tonic-gate grpMode))
333*0Sstevel@tonic-gate return 0;
334*0Sstevel@tonic-gate gt.model = modelGroup;
335*0Sstevel@tonic-gate gt.type = GroupToken::modelGroup;
336*0Sstevel@tonic-gate return 1;
337*0Sstevel@tonic-gate }
338*0Sstevel@tonic-gate case GroupToken::dataTagTemplateGroup:
339*0Sstevel@tonic-gate return parseDataTagTemplateGroup(nestingLevel + 1, declInputLevel, gt);
340*0Sstevel@tonic-gate default:
341*0Sstevel@tonic-gate groupTokenInvalidToken(tokenGrpo, allow);
342*0Sstevel@tonic-gate return 0;
343*0Sstevel@tonic-gate }
344*0Sstevel@tonic-gate break;
345*0Sstevel@tonic-gate case tokenRni:
346*0Sstevel@tonic-gate if (!allow.groupToken(GroupToken::pcdata)) {
347*0Sstevel@tonic-gate groupTokenInvalidToken(tokenRni, allow);
348*0Sstevel@tonic-gate return 0;
349*0Sstevel@tonic-gate }
350*0Sstevel@tonic-gate Syntax::ReservedName rn;
351*0Sstevel@tonic-gate if (!getIndicatedReservedName(&rn))
352*0Sstevel@tonic-gate return 0;
353*0Sstevel@tonic-gate if (rn != Syntax::rPCDATA) {
354*0Sstevel@tonic-gate StringC token(syntax().delimGeneral(Syntax::dRNI));
355*0Sstevel@tonic-gate token += syntax().reservedName(Syntax::rPCDATA);
356*0Sstevel@tonic-gate message(ParserMessages::invalidToken, StringMessageArg(token));
357*0Sstevel@tonic-gate return 0;
358*0Sstevel@tonic-gate }
359*0Sstevel@tonic-gate gt.type = GroupToken::pcdata;
360*0Sstevel@tonic-gate gt.contentToken = new PcdataToken;
361*0Sstevel@tonic-gate return 1;
362*0Sstevel@tonic-gate case tokenS:
363*0Sstevel@tonic-gate if (currentMarkup()) {
364*0Sstevel@tonic-gate extendS();
365*0Sstevel@tonic-gate currentMarkup()->addS(currentInput());
366*0Sstevel@tonic-gate }
367*0Sstevel@tonic-gate break;
368*0Sstevel@tonic-gate case tokenNameStart:
369*0Sstevel@tonic-gate switch (allow.nameStart()) {
370*0Sstevel@tonic-gate case GroupToken::elementToken:
371*0Sstevel@tonic-gate {
372*0Sstevel@tonic-gate extendNameToken(syntax().namelen(), ParserMessages::nameLength);
373*0Sstevel@tonic-gate gt.type = GroupToken::elementToken;
374*0Sstevel@tonic-gate StringC &buffer = nameBuffer();
375*0Sstevel@tonic-gate getCurrentToken(syntax().generalSubstTable(), buffer);
376*0Sstevel@tonic-gate if (currentMarkup())
377*0Sstevel@tonic-gate currentMarkup()->addName(currentInput());
378*0Sstevel@tonic-gate const ElementType *e = lookupCreateElement(buffer);
379*0Sstevel@tonic-gate ContentToken::OccurrenceIndicator oi
380*0Sstevel@tonic-gate = getOccurrenceIndicator(grpMode);
381*0Sstevel@tonic-gate gt.contentToken = new ElementToken(e, oi);
382*0Sstevel@tonic-gate return 1;
383*0Sstevel@tonic-gate }
384*0Sstevel@tonic-gate case GroupToken::name:
385*0Sstevel@tonic-gate case GroupToken::nameToken:
386*0Sstevel@tonic-gate extendNameToken(syntax().namelen(),
387*0Sstevel@tonic-gate token == GroupToken::name
388*0Sstevel@tonic-gate ? ParserMessages::nameLength
389*0Sstevel@tonic-gate : ParserMessages::nameTokenLength);
390*0Sstevel@tonic-gate getCurrentToken(syntax().generalSubstTable(), gt.token);
391*0Sstevel@tonic-gate gt.type = allow.nameStart();
392*0Sstevel@tonic-gate if (currentMarkup()) {
393*0Sstevel@tonic-gate if (gt.type == GroupToken::nameToken)
394*0Sstevel@tonic-gate currentMarkup()->addNameToken(currentInput());
395*0Sstevel@tonic-gate else
396*0Sstevel@tonic-gate currentMarkup()->addName(currentInput());
397*0Sstevel@tonic-gate }
398*0Sstevel@tonic-gate return 1;
399*0Sstevel@tonic-gate default:
400*0Sstevel@tonic-gate groupTokenInvalidToken(tokenNameStart, allow);
401*0Sstevel@tonic-gate return 0;
402*0Sstevel@tonic-gate }
403*0Sstevel@tonic-gate case tokenDigit:
404*0Sstevel@tonic-gate case tokenLcUcNmchar:
405*0Sstevel@tonic-gate if (!allow.groupToken(GroupToken::nameToken)) {
406*0Sstevel@tonic-gate groupTokenInvalidToken(token, allow);
407*0Sstevel@tonic-gate return 0;
408*0Sstevel@tonic-gate }
409*0Sstevel@tonic-gate extendNameToken(syntax().namelen(), ParserMessages::nameTokenLength);
410*0Sstevel@tonic-gate getCurrentToken(syntax().generalSubstTable(), gt.token);
411*0Sstevel@tonic-gate gt.type = GroupToken::nameToken;
412*0Sstevel@tonic-gate if (currentMarkup())
413*0Sstevel@tonic-gate currentMarkup()->addNameToken(currentInput());
414*0Sstevel@tonic-gate return 1;
415*0Sstevel@tonic-gate case tokenLit:
416*0Sstevel@tonic-gate case tokenLita:
417*0Sstevel@tonic-gate // parameter literal in data tag pattern
418*0Sstevel@tonic-gate if (!allow.groupToken(GroupToken::dataTagLiteral)) {
419*0Sstevel@tonic-gate groupTokenInvalidToken(token, allow);
420*0Sstevel@tonic-gate return 0;
421*0Sstevel@tonic-gate }
422*0Sstevel@tonic-gate if (!parseDataTagParameterLiteral(token == tokenLita, gt.text))
423*0Sstevel@tonic-gate return 0;
424*0Sstevel@tonic-gate gt.type = GroupToken::dataTagLiteral;
425*0Sstevel@tonic-gate if (currentMarkup())
426*0Sstevel@tonic-gate currentMarkup()->addLiteral(gt.text);
427*0Sstevel@tonic-gate return 1;
428*0Sstevel@tonic-gate case tokenAnd:
429*0Sstevel@tonic-gate case tokenSeq:
430*0Sstevel@tonic-gate case tokenOr:
431*0Sstevel@tonic-gate case tokenDtgc:
432*0Sstevel@tonic-gate case tokenGrpc:
433*0Sstevel@tonic-gate case tokenOpt:
434*0Sstevel@tonic-gate case tokenPlus:
435*0Sstevel@tonic-gate case tokenRep:
436*0Sstevel@tonic-gate groupTokenInvalidToken(token, allow);
437*0Sstevel@tonic-gate return 0;
438*0Sstevel@tonic-gate }
439*0Sstevel@tonic-gate }
440*0Sstevel@tonic-gate }
441*0Sstevel@tonic-gate
442*0Sstevel@tonic-gate
groupTokenInvalidToken(Token token,const AllowedGroupTokens & allow)443*0Sstevel@tonic-gate void Parser::groupTokenInvalidToken(Token token, const AllowedGroupTokens &allow)
444*0Sstevel@tonic-gate {
445*0Sstevel@tonic-gate message(ParserMessages::groupTokenInvalidToken,
446*0Sstevel@tonic-gate TokenMessageArg(token, grpMode, syntaxPointer(), sdPointer()),
447*0Sstevel@tonic-gate AllowedGroupTokensMessageArg(allow, syntaxPointer()));
448*0Sstevel@tonic-gate }
449*0Sstevel@tonic-gate
450*0Sstevel@tonic-gate
parseGroupConnector(const AllowedGroupConnectors & allow,unsigned declInputLevel,unsigned groupInputLevel,GroupConnector & gc)451*0Sstevel@tonic-gate Boolean Parser::parseGroupConnector(const AllowedGroupConnectors &allow,
452*0Sstevel@tonic-gate unsigned declInputLevel,
453*0Sstevel@tonic-gate unsigned groupInputLevel,
454*0Sstevel@tonic-gate GroupConnector &gc)
455*0Sstevel@tonic-gate {
456*0Sstevel@tonic-gate for (;;) {
457*0Sstevel@tonic-gate Token token = getToken(grpMode);
458*0Sstevel@tonic-gate switch (token) {
459*0Sstevel@tonic-gate case tokenEe:
460*0Sstevel@tonic-gate if (inputLevel() <= groupInputLevel) {
461*0Sstevel@tonic-gate message(ParserMessages::groupLevel);
462*0Sstevel@tonic-gate if (inputLevel() <= declInputLevel)
463*0Sstevel@tonic-gate return 0;
464*0Sstevel@tonic-gate }
465*0Sstevel@tonic-gate if (currentMarkup())
466*0Sstevel@tonic-gate currentMarkup()->addEntityEnd();
467*0Sstevel@tonic-gate popInputStack();
468*0Sstevel@tonic-gate break;
469*0Sstevel@tonic-gate case tokenS:
470*0Sstevel@tonic-gate if (currentMarkup()) {
471*0Sstevel@tonic-gate extendS();
472*0Sstevel@tonic-gate currentMarkup()->addS(currentInput());
473*0Sstevel@tonic-gate }
474*0Sstevel@tonic-gate break;
475*0Sstevel@tonic-gate case tokenPeroGrpo:
476*0Sstevel@tonic-gate if (inInstance()) {
477*0Sstevel@tonic-gate message(ParserMessages::peroGrpoProlog);
478*0Sstevel@tonic-gate break;
479*0Sstevel@tonic-gate }
480*0Sstevel@tonic-gate // fall through
481*0Sstevel@tonic-gate case tokenPeroNameStart:
482*0Sstevel@tonic-gate if (!sd().www())
483*0Sstevel@tonic-gate message(ParserMessages::groupEntityReference);
484*0Sstevel@tonic-gate else {
485*0Sstevel@tonic-gate ConstPtr<Entity> entity;
486*0Sstevel@tonic-gate Ptr<EntityOrigin> origin;
487*0Sstevel@tonic-gate if (!parseEntityReference(1, token == tokenPeroGrpo, entity, origin))
488*0Sstevel@tonic-gate return 0;
489*0Sstevel@tonic-gate if (!entity.isNull())
490*0Sstevel@tonic-gate entity->declReference(*this, origin);
491*0Sstevel@tonic-gate }
492*0Sstevel@tonic-gate break;
493*0Sstevel@tonic-gate case tokenUnrecognized:
494*0Sstevel@tonic-gate if (reportNonSgmlCharacter())
495*0Sstevel@tonic-gate break;
496*0Sstevel@tonic-gate {
497*0Sstevel@tonic-gate message(ParserMessages::groupCharacter,
498*0Sstevel@tonic-gate StringMessageArg(currentToken()),
499*0Sstevel@tonic-gate AllowedGroupConnectorsMessageArg(allow, syntaxPointer()));
500*0Sstevel@tonic-gate }
501*0Sstevel@tonic-gate return 0;
502*0Sstevel@tonic-gate case tokenAnd:
503*0Sstevel@tonic-gate if (!allow.groupConnector(GroupConnector::andGC)) {
504*0Sstevel@tonic-gate groupConnectorInvalidToken(tokenAnd, allow);
505*0Sstevel@tonic-gate return 0;
506*0Sstevel@tonic-gate }
507*0Sstevel@tonic-gate gc.type = GroupConnector::andGC;
508*0Sstevel@tonic-gate if (currentMarkup())
509*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dAND);
510*0Sstevel@tonic-gate return 1;
511*0Sstevel@tonic-gate case tokenSeq:
512*0Sstevel@tonic-gate if (!allow.groupConnector(GroupConnector::seqGC)) {
513*0Sstevel@tonic-gate groupConnectorInvalidToken(tokenSeq, allow);
514*0Sstevel@tonic-gate return 0;
515*0Sstevel@tonic-gate }
516*0Sstevel@tonic-gate gc.type = GroupConnector::seqGC;
517*0Sstevel@tonic-gate if (currentMarkup())
518*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dSEQ);
519*0Sstevel@tonic-gate return 1;
520*0Sstevel@tonic-gate case tokenOr:
521*0Sstevel@tonic-gate if (!allow.groupConnector(GroupConnector::orGC)) {
522*0Sstevel@tonic-gate groupConnectorInvalidToken(tokenOr, allow);
523*0Sstevel@tonic-gate return 0;
524*0Sstevel@tonic-gate }
525*0Sstevel@tonic-gate gc.type = GroupConnector::orGC;
526*0Sstevel@tonic-gate if (currentMarkup())
527*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dOR);
528*0Sstevel@tonic-gate return 1;
529*0Sstevel@tonic-gate case tokenDtgc:
530*0Sstevel@tonic-gate if (!allow.groupConnector(GroupConnector::dtgcGC)) {
531*0Sstevel@tonic-gate groupConnectorInvalidToken(tokenDtgc, allow);
532*0Sstevel@tonic-gate return 0;
533*0Sstevel@tonic-gate }
534*0Sstevel@tonic-gate gc.type = GroupConnector::dtgcGC;
535*0Sstevel@tonic-gate if (inputLevel() > groupInputLevel)
536*0Sstevel@tonic-gate message(ParserMessages::groupParameterEntityNotEnded);
537*0Sstevel@tonic-gate if (currentMarkup())
538*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dDTGC);
539*0Sstevel@tonic-gate return 1;
540*0Sstevel@tonic-gate case tokenGrpc:
541*0Sstevel@tonic-gate if (!allow.groupConnector(GroupConnector::grpcGC)) {
542*0Sstevel@tonic-gate groupConnectorInvalidToken(tokenGrpc, allow);
543*0Sstevel@tonic-gate return 0;
544*0Sstevel@tonic-gate }
545*0Sstevel@tonic-gate gc.type = GroupConnector::grpcGC;
546*0Sstevel@tonic-gate if (inputLevel() > groupInputLevel)
547*0Sstevel@tonic-gate message(ParserMessages::groupParameterEntityNotEnded);
548*0Sstevel@tonic-gate if (currentMarkup())
549*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dGRPC);
550*0Sstevel@tonic-gate return 1;
551*0Sstevel@tonic-gate default:
552*0Sstevel@tonic-gate groupConnectorInvalidToken(token, allow);
553*0Sstevel@tonic-gate return 0;
554*0Sstevel@tonic-gate }
555*0Sstevel@tonic-gate }
556*0Sstevel@tonic-gate }
557*0Sstevel@tonic-gate
groupConnectorInvalidToken(Token token,const AllowedGroupConnectors & allow)558*0Sstevel@tonic-gate void Parser::groupConnectorInvalidToken(Token token,
559*0Sstevel@tonic-gate const AllowedGroupConnectors &allow)
560*0Sstevel@tonic-gate {
561*0Sstevel@tonic-gate message(ParserMessages::connectorInvalidToken,
562*0Sstevel@tonic-gate TokenMessageArg(token, grpMode, syntaxPointer(), sdPointer()),
563*0Sstevel@tonic-gate AllowedGroupConnectorsMessageArg(allow, syntaxPointer()));
564*0Sstevel@tonic-gate }
565*0Sstevel@tonic-gate
parseElementNameGroup(unsigned declInputLevel,Param & parm)566*0Sstevel@tonic-gate Boolean Parser::parseElementNameGroup(unsigned declInputLevel, Param &parm)
567*0Sstevel@tonic-gate {
568*0Sstevel@tonic-gate if (!parseNameGroup(declInputLevel, parm))
569*0Sstevel@tonic-gate return 0;
570*0Sstevel@tonic-gate parm.elementVector.resize(parm.nameTokenVector.size());
571*0Sstevel@tonic-gate for (size_t i = 0; i < parm.nameTokenVector.size(); i++)
572*0Sstevel@tonic-gate parm.elementVector[i] = lookupCreateElement(parm.nameTokenVector[i].name);
573*0Sstevel@tonic-gate return 1;
574*0Sstevel@tonic-gate }
575*0Sstevel@tonic-gate
parseEntityReferenceNameGroup(Boolean & ignore)576*0Sstevel@tonic-gate Boolean Parser::parseEntityReferenceNameGroup(Boolean &ignore)
577*0Sstevel@tonic-gate {
578*0Sstevel@tonic-gate Param parm;
579*0Sstevel@tonic-gate if (!parseNameGroup(inputLevel(), parm))
580*0Sstevel@tonic-gate return 0;
581*0Sstevel@tonic-gate if (inInstance()) {
582*0Sstevel@tonic-gate for (size_t i = 0; i < parm.nameTokenVector.size(); i++) {
583*0Sstevel@tonic-gate const Lpd *lpd = lookupLpd(parm.nameTokenVector[i].name).pointer();
584*0Sstevel@tonic-gate if (lpd && lpd->active()) {
585*0Sstevel@tonic-gate ignore = 0;
586*0Sstevel@tonic-gate return 1;
587*0Sstevel@tonic-gate }
588*0Sstevel@tonic-gate }
589*0Sstevel@tonic-gate }
590*0Sstevel@tonic-gate ignore = 1;
591*0Sstevel@tonic-gate return 1;
592*0Sstevel@tonic-gate }
593*0Sstevel@tonic-gate
parseTagNameGroup(Boolean & active)594*0Sstevel@tonic-gate Boolean Parser::parseTagNameGroup(Boolean &active)
595*0Sstevel@tonic-gate {
596*0Sstevel@tonic-gate Param parm;
597*0Sstevel@tonic-gate if (!parseNameGroup(inputLevel(), parm))
598*0Sstevel@tonic-gate return 0;
599*0Sstevel@tonic-gate active = 0;
600*0Sstevel@tonic-gate return 1;
601*0Sstevel@tonic-gate }
602*0Sstevel@tonic-gate
parseNameGroup(unsigned declInputLevel,Param & parm)603*0Sstevel@tonic-gate Boolean Parser::parseNameGroup(unsigned declInputLevel, Param &parm)
604*0Sstevel@tonic-gate {
605*0Sstevel@tonic-gate static AllowedGroupTokens allowName(GroupToken::name);
606*0Sstevel@tonic-gate return parseGroup(allowName, declInputLevel, parm);
607*0Sstevel@tonic-gate }
608*0Sstevel@tonic-gate
parseNameTokenGroup(unsigned declInputLevel,Param & parm)609*0Sstevel@tonic-gate Boolean Parser::parseNameTokenGroup(unsigned declInputLevel, Param &parm)
610*0Sstevel@tonic-gate {
611*0Sstevel@tonic-gate static AllowedGroupTokens allowNameToken(GroupToken::nameToken);
612*0Sstevel@tonic-gate return parseGroup(allowNameToken, declInputLevel, parm);
613*0Sstevel@tonic-gate }
614*0Sstevel@tonic-gate
615*0Sstevel@tonic-gate static
groupContains(const Vector<NameToken> & vec,const StringC & str)616*0Sstevel@tonic-gate Boolean groupContains(const Vector<NameToken> &vec, const StringC &str)
617*0Sstevel@tonic-gate {
618*0Sstevel@tonic-gate for (size_t i = 0; i < vec.size(); i++)
619*0Sstevel@tonic-gate if (vec[i].name == str)
620*0Sstevel@tonic-gate return 1;
621*0Sstevel@tonic-gate return 0;
622*0Sstevel@tonic-gate }
623*0Sstevel@tonic-gate
parseGroup(const AllowedGroupTokens & allowToken,unsigned declInputLevel,Param & parm)624*0Sstevel@tonic-gate Boolean Parser::parseGroup(const AllowedGroupTokens &allowToken,
625*0Sstevel@tonic-gate unsigned declInputLevel,
626*0Sstevel@tonic-gate Param &parm)
627*0Sstevel@tonic-gate {
628*0Sstevel@tonic-gate unsigned groupInputLevel = inputLevel();
629*0Sstevel@tonic-gate int nDuplicates = 0;
630*0Sstevel@tonic-gate Vector<NameToken> &vec = parm.nameTokenVector;
631*0Sstevel@tonic-gate vec.clear();
632*0Sstevel@tonic-gate GroupConnector::Type connector = GroupConnector::grpcGC;
633*0Sstevel@tonic-gate GroupToken gt;
634*0Sstevel@tonic-gate for (;;) {
635*0Sstevel@tonic-gate if (!parseGroupToken(allowToken, 0, declInputLevel, groupInputLevel, gt))
636*0Sstevel@tonic-gate return 0;
637*0Sstevel@tonic-gate if (groupContains(vec, gt.token)) {
638*0Sstevel@tonic-gate nDuplicates++;
639*0Sstevel@tonic-gate message(ParserMessages::duplicateGroupToken,
640*0Sstevel@tonic-gate StringMessageArg(gt.token));
641*0Sstevel@tonic-gate }
642*0Sstevel@tonic-gate else {
643*0Sstevel@tonic-gate vec.resize(vec.size() + 1);
644*0Sstevel@tonic-gate gt.token.swap(vec.back().name);
645*0Sstevel@tonic-gate getCurrentToken(vec.back().origName);
646*0Sstevel@tonic-gate vec.back().loc = currentLocation();
647*0Sstevel@tonic-gate }
648*0Sstevel@tonic-gate GroupConnector gc;
649*0Sstevel@tonic-gate static AllowedGroupConnectors allowAnyConnectorGrpc(GroupConnector::orGC,
650*0Sstevel@tonic-gate GroupConnector::andGC,
651*0Sstevel@tonic-gate GroupConnector::seqGC,
652*0Sstevel@tonic-gate GroupConnector::grpcGC);
653*0Sstevel@tonic-gate
654*0Sstevel@tonic-gate if (!parseGroupConnector(allowAnyConnectorGrpc, declInputLevel,
655*0Sstevel@tonic-gate groupInputLevel, gc))
656*0Sstevel@tonic-gate return 0;
657*0Sstevel@tonic-gate if (gc.type == GroupConnector::grpcGC)
658*0Sstevel@tonic-gate break;
659*0Sstevel@tonic-gate if (options().warnNameGroupNotOr) {
660*0Sstevel@tonic-gate if (gc.type != GroupConnector::orGC)
661*0Sstevel@tonic-gate message(ParserMessages::nameGroupNotOr);
662*0Sstevel@tonic-gate }
663*0Sstevel@tonic-gate else if (options().warnShould) {
664*0Sstevel@tonic-gate if (connector == GroupConnector::grpcGC)
665*0Sstevel@tonic-gate connector = gc.type;
666*0Sstevel@tonic-gate else if (gc.type != connector) {
667*0Sstevel@tonic-gate message(ParserMessages::mixedConnectors);
668*0Sstevel@tonic-gate connector = gc.type;
669*0Sstevel@tonic-gate }
670*0Sstevel@tonic-gate }
671*0Sstevel@tonic-gate }
672*0Sstevel@tonic-gate if (nDuplicates + vec.size() > syntax().grpcnt())
673*0Sstevel@tonic-gate message(ParserMessages::groupCount, NumberMessageArg(syntax().grpcnt()));
674*0Sstevel@tonic-gate return 1;
675*0Sstevel@tonic-gate }
676*0Sstevel@tonic-gate
parseDataTagGroup(unsigned nestingLevel,unsigned declInputLevel,GroupToken & result)677*0Sstevel@tonic-gate Boolean Parser::parseDataTagGroup(unsigned nestingLevel,
678*0Sstevel@tonic-gate unsigned declInputLevel, GroupToken &result)
679*0Sstevel@tonic-gate {
680*0Sstevel@tonic-gate if (nestingLevel - 1 == syntax().grplvl())
681*0Sstevel@tonic-gate message(ParserMessages::grplvl, NumberMessageArg(syntax().grplvl()));
682*0Sstevel@tonic-gate unsigned groupInputLevel = inputLevel();
683*0Sstevel@tonic-gate GroupToken gt;
684*0Sstevel@tonic-gate static AllowedGroupTokens allowName(GroupToken::name);
685*0Sstevel@tonic-gate if (!parseGroupToken(allowName, nestingLevel, declInputLevel,
686*0Sstevel@tonic-gate groupInputLevel, gt))
687*0Sstevel@tonic-gate return 0;
688*0Sstevel@tonic-gate const ElementType *element = lookupCreateElement(gt.token);
689*0Sstevel@tonic-gate GroupConnector gc;
690*0Sstevel@tonic-gate static AllowedGroupConnectors allowSeq(GroupConnector::seqGC);
691*0Sstevel@tonic-gate if (!parseGroupConnector(allowSeq, declInputLevel, groupInputLevel, gc))
692*0Sstevel@tonic-gate return 0;
693*0Sstevel@tonic-gate static AllowedGroupTokens
694*0Sstevel@tonic-gate allowDataTagLiteralDataTagTemplateGroup(GroupToken::dataTagLiteral,
695*0Sstevel@tonic-gate GroupToken::dataTagTemplateGroup);
696*0Sstevel@tonic-gate if (!parseGroupToken(allowDataTagLiteralDataTagTemplateGroup,
697*0Sstevel@tonic-gate nestingLevel,
698*0Sstevel@tonic-gate declInputLevel,
699*0Sstevel@tonic-gate groupInputLevel,
700*0Sstevel@tonic-gate gt))
701*0Sstevel@tonic-gate return 0;
702*0Sstevel@tonic-gate Vector<Text> templates;
703*0Sstevel@tonic-gate if (gt.type == GroupToken::dataTagTemplateGroup)
704*0Sstevel@tonic-gate gt.textVector.swap(templates);
705*0Sstevel@tonic-gate else {
706*0Sstevel@tonic-gate templates.resize(1);
707*0Sstevel@tonic-gate gt.text.swap(templates[0]);
708*0Sstevel@tonic-gate }
709*0Sstevel@tonic-gate static AllowedGroupConnectors allowSeqDtgc(GroupConnector::seqGC,
710*0Sstevel@tonic-gate GroupConnector::dtgcGC);
711*0Sstevel@tonic-gate if (!parseGroupConnector(allowSeqDtgc, declInputLevel, groupInputLevel, gc))
712*0Sstevel@tonic-gate return 0;
713*0Sstevel@tonic-gate NCVector<Owner<ContentToken> > vec(2);
714*0Sstevel@tonic-gate vec[1] = new PcdataToken;
715*0Sstevel@tonic-gate if (gc.type != GroupConnector::dtgcGC) {
716*0Sstevel@tonic-gate static AllowedGroupTokens allowDataTagLiteral(GroupToken::dataTagLiteral);
717*0Sstevel@tonic-gate if (!parseGroupToken(allowDataTagLiteral,
718*0Sstevel@tonic-gate nestingLevel,
719*0Sstevel@tonic-gate declInputLevel,
720*0Sstevel@tonic-gate groupInputLevel,
721*0Sstevel@tonic-gate gt))
722*0Sstevel@tonic-gate return 0;
723*0Sstevel@tonic-gate vec[0] = new DataTagElementToken(element, templates, gt.text);
724*0Sstevel@tonic-gate static AllowedGroupConnectors allowDtgc(GroupConnector::dtgcGC);
725*0Sstevel@tonic-gate if (!parseGroupConnector(allowDtgc, declInputLevel, groupInputLevel, gc))
726*0Sstevel@tonic-gate return 0;
727*0Sstevel@tonic-gate }
728*0Sstevel@tonic-gate else
729*0Sstevel@tonic-gate vec[0] = new DataTagElementToken(element, templates);
730*0Sstevel@tonic-gate ContentToken::OccurrenceIndicator oi = getOccurrenceIndicator(grpMode);
731*0Sstevel@tonic-gate result.contentToken = new DataTagGroup(vec, oi);
732*0Sstevel@tonic-gate result.type = GroupToken::dataTagGroup;
733*0Sstevel@tonic-gate return 1;
734*0Sstevel@tonic-gate }
735*0Sstevel@tonic-gate
parseDataTagTemplateGroup(unsigned nestingLevel,unsigned declInputLevel,GroupToken & result)736*0Sstevel@tonic-gate Boolean Parser::parseDataTagTemplateGroup(unsigned nestingLevel,
737*0Sstevel@tonic-gate unsigned declInputLevel,
738*0Sstevel@tonic-gate GroupToken &result)
739*0Sstevel@tonic-gate {
740*0Sstevel@tonic-gate if (nestingLevel - 1 == syntax().grplvl())
741*0Sstevel@tonic-gate message(ParserMessages::grplvl, NumberMessageArg(syntax().grplvl()));
742*0Sstevel@tonic-gate unsigned groupInputLevel = inputLevel();
743*0Sstevel@tonic-gate Vector<Text> &vec = result.textVector;
744*0Sstevel@tonic-gate for (;;) {
745*0Sstevel@tonic-gate GroupToken gt;
746*0Sstevel@tonic-gate static AllowedGroupTokens allowDataTagLiteral(GroupToken::dataTagLiteral);
747*0Sstevel@tonic-gate if (!parseGroupToken(allowDataTagLiteral,
748*0Sstevel@tonic-gate nestingLevel,
749*0Sstevel@tonic-gate declInputLevel,
750*0Sstevel@tonic-gate groupInputLevel,
751*0Sstevel@tonic-gate gt))
752*0Sstevel@tonic-gate return 0;
753*0Sstevel@tonic-gate if (vec.size() == syntax().grpcnt())
754*0Sstevel@tonic-gate message(ParserMessages::groupCount, NumberMessageArg(syntax().grpcnt()));
755*0Sstevel@tonic-gate vec.resize(vec.size() + 1);
756*0Sstevel@tonic-gate gt.text.swap(vec.back());
757*0Sstevel@tonic-gate static AllowedGroupConnectors allowOrGrpc(GroupConnector::orGC,
758*0Sstevel@tonic-gate GroupConnector::grpcGC);
759*0Sstevel@tonic-gate GroupConnector gc;
760*0Sstevel@tonic-gate if (!parseGroupConnector(allowOrGrpc, declInputLevel, groupInputLevel, gc))
761*0Sstevel@tonic-gate return 0;
762*0Sstevel@tonic-gate if (gc.type == GroupConnector::grpcGC)
763*0Sstevel@tonic-gate break;
764*0Sstevel@tonic-gate }
765*0Sstevel@tonic-gate return 1;
766*0Sstevel@tonic-gate }
767*0Sstevel@tonic-gate
parseModelGroup(unsigned nestingLevel,unsigned declInputLevel,ModelGroup * & group,Mode oiMode)768*0Sstevel@tonic-gate Boolean Parser::parseModelGroup(unsigned nestingLevel, unsigned declInputLevel,
769*0Sstevel@tonic-gate ModelGroup *&group, Mode oiMode)
770*0Sstevel@tonic-gate {
771*0Sstevel@tonic-gate if (nestingLevel - 1 == syntax().grplvl())
772*0Sstevel@tonic-gate message(ParserMessages::grplvl, NumberMessageArg(syntax().grplvl()));
773*0Sstevel@tonic-gate unsigned groupInputLevel = inputLevel();
774*0Sstevel@tonic-gate GroupToken gt;
775*0Sstevel@tonic-gate NCVector<Owner<ContentToken> > tokenVector;
776*0Sstevel@tonic-gate GroupConnector::Type connector = GroupConnector::grpcGC;
777*0Sstevel@tonic-gate
778*0Sstevel@tonic-gate static AllowedGroupTokens allowContentToken(GroupToken::pcdata,
779*0Sstevel@tonic-gate GroupToken::dataTagGroup,
780*0Sstevel@tonic-gate GroupToken::elementToken,
781*0Sstevel@tonic-gate GroupToken::modelGroup);
782*0Sstevel@tonic-gate static AllowedGroupConnectors allowAnyConnectorGrpc(GroupConnector::orGC,
783*0Sstevel@tonic-gate GroupConnector::andGC,
784*0Sstevel@tonic-gate GroupConnector::seqGC,
785*0Sstevel@tonic-gate GroupConnector::grpcGC);
786*0Sstevel@tonic-gate
787*0Sstevel@tonic-gate static AllowedGroupConnectors allowOrGrpc(GroupConnector::orGC,
788*0Sstevel@tonic-gate GroupConnector::grpcGC);
789*0Sstevel@tonic-gate static AllowedGroupConnectors allowAndGrpc(GroupConnector::andGC,
790*0Sstevel@tonic-gate GroupConnector::grpcGC);
791*0Sstevel@tonic-gate static AllowedGroupConnectors allowSeqGrpc(GroupConnector::seqGC,
792*0Sstevel@tonic-gate GroupConnector::grpcGC);
793*0Sstevel@tonic-gate const AllowedGroupConnectors *connectorp = &allowAnyConnectorGrpc;
794*0Sstevel@tonic-gate
795*0Sstevel@tonic-gate GroupConnector gc;
796*0Sstevel@tonic-gate Boolean pcdataCheck = 0;
797*0Sstevel@tonic-gate do {
798*0Sstevel@tonic-gate if (!parseGroupToken(allowContentToken, nestingLevel, declInputLevel,
799*0Sstevel@tonic-gate groupInputLevel, gt))
800*0Sstevel@tonic-gate return 0;
801*0Sstevel@tonic-gate ContentToken *contentToken;
802*0Sstevel@tonic-gate if (gt.type == GroupToken::modelGroup)
803*0Sstevel@tonic-gate contentToken = gt.model.extract();
804*0Sstevel@tonic-gate else
805*0Sstevel@tonic-gate contentToken = gt.contentToken.extract();
806*0Sstevel@tonic-gate if (tokenVector.size() == syntax().grpcnt())
807*0Sstevel@tonic-gate message(ParserMessages::groupCount, NumberMessageArg(syntax().grpcnt()));
808*0Sstevel@tonic-gate tokenVector.resize(tokenVector.size() + 1);
809*0Sstevel@tonic-gate tokenVector.back() = contentToken;
810*0Sstevel@tonic-gate if (!parseGroupConnector(*connectorp, declInputLevel, groupInputLevel, gc))
811*0Sstevel@tonic-gate return 0;
812*0Sstevel@tonic-gate if (options().warnMixedContentRepOrGroup && gt.type == GroupToken::pcdata) {
813*0Sstevel@tonic-gate if (tokenVector.size() != 1)
814*0Sstevel@tonic-gate message(ParserMessages::pcdataNotFirstInGroup);
815*0Sstevel@tonic-gate else if (gc.type == GroupConnector::seqGC)
816*0Sstevel@tonic-gate message(ParserMessages::pcdataInSeqGroup);
817*0Sstevel@tonic-gate else
818*0Sstevel@tonic-gate pcdataCheck = 1;
819*0Sstevel@tonic-gate if (nestingLevel != 1)
820*0Sstevel@tonic-gate message(ParserMessages::pcdataInNestedModelGroup);
821*0Sstevel@tonic-gate }
822*0Sstevel@tonic-gate else if (pcdataCheck) {
823*0Sstevel@tonic-gate if (gt.type == GroupToken::modelGroup)
824*0Sstevel@tonic-gate message(ParserMessages::pcdataGroupMemberModelGroup);
825*0Sstevel@tonic-gate if (contentToken->occurrenceIndicator() != ContentToken::none)
826*0Sstevel@tonic-gate message(ParserMessages::pcdataGroupMemberOccurrenceIndicator);
827*0Sstevel@tonic-gate }
828*0Sstevel@tonic-gate if (tokenVector.size() == 1) {
829*0Sstevel@tonic-gate connector = gc.type;
830*0Sstevel@tonic-gate switch (gc.type) {
831*0Sstevel@tonic-gate case GroupConnector::orGC:
832*0Sstevel@tonic-gate connectorp = &allowOrGrpc;
833*0Sstevel@tonic-gate break;
834*0Sstevel@tonic-gate case GroupConnector::seqGC:
835*0Sstevel@tonic-gate connectorp = &allowSeqGrpc;
836*0Sstevel@tonic-gate break;
837*0Sstevel@tonic-gate case GroupConnector::andGC:
838*0Sstevel@tonic-gate connectorp = &allowAndGrpc;
839*0Sstevel@tonic-gate if (options().warnAndGroup)
840*0Sstevel@tonic-gate message(ParserMessages::andGroup);
841*0Sstevel@tonic-gate break;
842*0Sstevel@tonic-gate default:
843*0Sstevel@tonic-gate break;
844*0Sstevel@tonic-gate }
845*0Sstevel@tonic-gate }
846*0Sstevel@tonic-gate } while (gc.type != GroupConnector::grpcGC);
847*0Sstevel@tonic-gate ContentToken::OccurrenceIndicator oi
848*0Sstevel@tonic-gate = getOccurrenceIndicator(oiMode);
849*0Sstevel@tonic-gate switch (connector) {
850*0Sstevel@tonic-gate case GroupConnector::orGC:
851*0Sstevel@tonic-gate group = new OrModelGroup(tokenVector, oi);
852*0Sstevel@tonic-gate if (pcdataCheck && oi != ContentToken::rep)
853*0Sstevel@tonic-gate message(ParserMessages::pcdataGroupNotRep);
854*0Sstevel@tonic-gate break;
855*0Sstevel@tonic-gate case GroupConnector::grpcGC:
856*0Sstevel@tonic-gate if (pcdataCheck && oi != ContentToken::rep && oi != ContentToken::none)
857*0Sstevel@tonic-gate message(ParserMessages::pcdataGroupNotRep);
858*0Sstevel@tonic-gate // fall through
859*0Sstevel@tonic-gate case GroupConnector::seqGC:
860*0Sstevel@tonic-gate group = new SeqModelGroup(tokenVector, oi);
861*0Sstevel@tonic-gate break;
862*0Sstevel@tonic-gate case GroupConnector::andGC:
863*0Sstevel@tonic-gate group = new AndModelGroup(tokenVector, oi);
864*0Sstevel@tonic-gate break;
865*0Sstevel@tonic-gate default:
866*0Sstevel@tonic-gate break;
867*0Sstevel@tonic-gate }
868*0Sstevel@tonic-gate return 1;
869*0Sstevel@tonic-gate }
870*0Sstevel@tonic-gate
871*0Sstevel@tonic-gate ContentToken::OccurrenceIndicator
getOccurrenceIndicator(Mode oiMode)872*0Sstevel@tonic-gate Parser::getOccurrenceIndicator(Mode oiMode)
873*0Sstevel@tonic-gate {
874*0Sstevel@tonic-gate Token token = getToken(oiMode);
875*0Sstevel@tonic-gate switch (token) {
876*0Sstevel@tonic-gate case tokenPlus:
877*0Sstevel@tonic-gate if (currentMarkup())
878*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dPLUS);
879*0Sstevel@tonic-gate return ContentToken::plus;
880*0Sstevel@tonic-gate case tokenOpt:
881*0Sstevel@tonic-gate if (currentMarkup())
882*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dOPT);
883*0Sstevel@tonic-gate return ContentToken::opt;
884*0Sstevel@tonic-gate case tokenRep:
885*0Sstevel@tonic-gate if (currentMarkup())
886*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dREP);
887*0Sstevel@tonic-gate return ContentToken::rep;
888*0Sstevel@tonic-gate default:
889*0Sstevel@tonic-gate currentInput()->ungetToken();
890*0Sstevel@tonic-gate return ContentToken::none;
891*0Sstevel@tonic-gate }
892*0Sstevel@tonic-gate }
893*0Sstevel@tonic-gate
parseMinimumLiteral(Boolean lita,Text & text)894*0Sstevel@tonic-gate Boolean Parser::parseMinimumLiteral(Boolean lita, Text &text)
895*0Sstevel@tonic-gate {
896*0Sstevel@tonic-gate return parseLiteral(lita ? mlitaMode : mlitMode, mlitMode,
897*0Sstevel@tonic-gate Syntax::referenceQuantity(Syntax::qLITLEN),
898*0Sstevel@tonic-gate ParserMessages::minimumLiteralLength,
899*0Sstevel@tonic-gate literalSingleSpace|literalMinimumData
900*0Sstevel@tonic-gate |(eventsWanted().wantPrologMarkup()
901*0Sstevel@tonic-gate ? literalDelimInfo
902*0Sstevel@tonic-gate : 0),
903*0Sstevel@tonic-gate text);
904*0Sstevel@tonic-gate }
905*0Sstevel@tonic-gate
parseSystemIdentifier(Boolean lita,Text & text)906*0Sstevel@tonic-gate Boolean Parser::parseSystemIdentifier(Boolean lita, Text &text)
907*0Sstevel@tonic-gate {
908*0Sstevel@tonic-gate return parseLiteral(lita ? slitaMode : slitMode, slitMode, syntax().litlen(),
909*0Sstevel@tonic-gate ParserMessages::systemIdentifierLength,
910*0Sstevel@tonic-gate (eventsWanted().wantPrologMarkup()
911*0Sstevel@tonic-gate ? literalDelimInfo
912*0Sstevel@tonic-gate : 0), text);
913*0Sstevel@tonic-gate }
914*0Sstevel@tonic-gate
parseParameterLiteral(Boolean lita,Text & text)915*0Sstevel@tonic-gate Boolean Parser::parseParameterLiteral(Boolean lita, Text &text)
916*0Sstevel@tonic-gate {
917*0Sstevel@tonic-gate return parseLiteral(lita ? plitaMode : plitMode, pliteMode, syntax().litlen(),
918*0Sstevel@tonic-gate ParserMessages::parameterLiteralLength,
919*0Sstevel@tonic-gate (eventsWanted().wantPrologMarkup()
920*0Sstevel@tonic-gate ? literalDelimInfo
921*0Sstevel@tonic-gate : 0),
922*0Sstevel@tonic-gate text);
923*0Sstevel@tonic-gate }
924*0Sstevel@tonic-gate
parseDataTagParameterLiteral(Boolean lita,Text & text)925*0Sstevel@tonic-gate Boolean Parser::parseDataTagParameterLiteral(Boolean lita, Text &text)
926*0Sstevel@tonic-gate {
927*0Sstevel@tonic-gate return parseLiteral(lita ? plitaMode : plitMode, pliteMode,
928*0Sstevel@tonic-gate syntax().dtemplen(),
929*0Sstevel@tonic-gate ParserMessages::dataTagPatternLiteralLength,
930*0Sstevel@tonic-gate literalDataTag
931*0Sstevel@tonic-gate | (eventsWanted().wantPrologMarkup()
932*0Sstevel@tonic-gate ? literalDelimInfo
933*0Sstevel@tonic-gate : 0),
934*0Sstevel@tonic-gate text);
935*0Sstevel@tonic-gate }
936*0Sstevel@tonic-gate
parseIndicatedReservedName(const AllowedParams & allow,Param & parm)937*0Sstevel@tonic-gate Boolean Parser::parseIndicatedReservedName(const AllowedParams &allow,
938*0Sstevel@tonic-gate Param &parm)
939*0Sstevel@tonic-gate {
940*0Sstevel@tonic-gate Syntax::ReservedName rn;
941*0Sstevel@tonic-gate if (!getIndicatedReservedName(&rn))
942*0Sstevel@tonic-gate return 0;
943*0Sstevel@tonic-gate if (!allow.reservedName(rn)) {
944*0Sstevel@tonic-gate message(ParserMessages::invalidReservedName,
945*0Sstevel@tonic-gate StringMessageArg(currentToken()));
946*0Sstevel@tonic-gate return 0;
947*0Sstevel@tonic-gate }
948*0Sstevel@tonic-gate parm.type = Param::indicatedReservedName + rn;
949*0Sstevel@tonic-gate return 1;
950*0Sstevel@tonic-gate }
951*0Sstevel@tonic-gate
parseReservedName(const AllowedParams & allow,Param & parm)952*0Sstevel@tonic-gate Boolean Parser::parseReservedName(const AllowedParams &allow,
953*0Sstevel@tonic-gate Param &parm)
954*0Sstevel@tonic-gate {
955*0Sstevel@tonic-gate Syntax::ReservedName rn;
956*0Sstevel@tonic-gate if (!getReservedName(&rn))
957*0Sstevel@tonic-gate return 0;
958*0Sstevel@tonic-gate if (!allow.reservedName(rn)) {
959*0Sstevel@tonic-gate message(ParserMessages::invalidReservedName,
960*0Sstevel@tonic-gate StringMessageArg(syntax().reservedName(rn)));
961*0Sstevel@tonic-gate return 0;
962*0Sstevel@tonic-gate }
963*0Sstevel@tonic-gate parm.type = Param::reservedName + rn;
964*0Sstevel@tonic-gate return 1;
965*0Sstevel@tonic-gate }
966*0Sstevel@tonic-gate
967*0Sstevel@tonic-gate
parseAttributeValueParam(Param & parm)968*0Sstevel@tonic-gate Boolean Parser::parseAttributeValueParam(Param &parm)
969*0Sstevel@tonic-gate {
970*0Sstevel@tonic-gate extendNameToken(syntax().litlen() > syntax().normsep()
971*0Sstevel@tonic-gate ? syntax().litlen() - syntax().normsep()
972*0Sstevel@tonic-gate : 0,
973*0Sstevel@tonic-gate ParserMessages::attributeValueLength);
974*0Sstevel@tonic-gate parm.type = Param::attributeValue;
975*0Sstevel@tonic-gate Text text;
976*0Sstevel@tonic-gate text.addChars(currentInput()->currentTokenStart(),
977*0Sstevel@tonic-gate currentInput()->currentTokenLength(),
978*0Sstevel@tonic-gate currentLocation());
979*0Sstevel@tonic-gate text.swap(parm.literalText);
980*0Sstevel@tonic-gate if (currentMarkup())
981*0Sstevel@tonic-gate currentMarkup()->addAttributeValue(currentInput());
982*0Sstevel@tonic-gate return 1;
983*0Sstevel@tonic-gate }
984*0Sstevel@tonic-gate
getIndicatedReservedName(Syntax::ReservedName * result)985*0Sstevel@tonic-gate Boolean Parser::getIndicatedReservedName(Syntax::ReservedName *result)
986*0Sstevel@tonic-gate {
987*0Sstevel@tonic-gate if (currentMarkup())
988*0Sstevel@tonic-gate currentMarkup()->addDelim(Syntax::dRNI);
989*0Sstevel@tonic-gate InputSource *in = currentInput();
990*0Sstevel@tonic-gate in->startToken();
991*0Sstevel@tonic-gate if (!syntax().isNameStartCharacter(in->tokenChar(messenger()))) {
992*0Sstevel@tonic-gate message(ParserMessages::rniNameStart);
993*0Sstevel@tonic-gate return 0;
994*0Sstevel@tonic-gate }
995*0Sstevel@tonic-gate extendNameToken(syntax().namelen(), ParserMessages::nameLength);
996*0Sstevel@tonic-gate StringC &buffer = nameBuffer();
997*0Sstevel@tonic-gate getCurrentToken(syntax().generalSubstTable(), buffer);
998*0Sstevel@tonic-gate if (!syntax().lookupReservedName(buffer, result)) {
999*0Sstevel@tonic-gate message(ParserMessages::noSuchReservedName, StringMessageArg(buffer));
1000*0Sstevel@tonic-gate return 0;
1001*0Sstevel@tonic-gate }
1002*0Sstevel@tonic-gate if (currentMarkup())
1003*0Sstevel@tonic-gate currentMarkup()->addReservedName(*result, currentInput());
1004*0Sstevel@tonic-gate return 1;
1005*0Sstevel@tonic-gate }
1006*0Sstevel@tonic-gate
getReservedName(Syntax::ReservedName * result)1007*0Sstevel@tonic-gate Boolean Parser::getReservedName(Syntax::ReservedName *result)
1008*0Sstevel@tonic-gate {
1009*0Sstevel@tonic-gate extendNameToken(syntax().namelen(), ParserMessages::nameLength);
1010*0Sstevel@tonic-gate StringC &buffer = nameBuffer();
1011*0Sstevel@tonic-gate getCurrentToken(syntax().generalSubstTable(), buffer);
1012*0Sstevel@tonic-gate if (!syntax().lookupReservedName(buffer, result)) {
1013*0Sstevel@tonic-gate message(ParserMessages::noSuchReservedName, StringMessageArg(buffer));
1014*0Sstevel@tonic-gate return 0;
1015*0Sstevel@tonic-gate }
1016*0Sstevel@tonic-gate if (currentMarkup())
1017*0Sstevel@tonic-gate currentMarkup()->addReservedName(*result, currentInput());
1018*0Sstevel@tonic-gate return 1;
1019*0Sstevel@tonic-gate }
1020*0Sstevel@tonic-gate
1021*0Sstevel@tonic-gate
1022*0Sstevel@tonic-gate #ifdef SP_NAMESPACE
1023*0Sstevel@tonic-gate }
1024*0Sstevel@tonic-gate #endif
1025