parseParam.C 29 KB

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