Parser.jay 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. %{
  2. // XPath/XSLT Pattern parser
  3. //
  4. // Author: Piers Haken <[email protected]>
  5. // Atsushi Enomoto <[email protected]>
  6. //
  7. // IMPORTANT:
  8. // Do not edit "PatternParser.jay". It is autogenerated from
  9. // Parser.jay. It will be overwritten!
  10. //
  11. using System;
  12. using System.Collections;
  13. using System.Xml;
  14. using System.Xml.XPath;
  15. #if XSLT_PATTERN
  16. namespace Mono.Xml.Xsl
  17. #else
  18. namespace Mono.Xml.XPath
  19. #endif
  20. {
  21. #if XSLT_PATTERN
  22. internal class XsltPatternParser
  23. #else
  24. internal class XPathParser
  25. #endif
  26. {
  27. internal System.Xml.Xsl.IStaticXsltContext Context;
  28. #if XSLT_PATTERN
  29. public XsltPatternParser () : this (null) {}
  30. internal XsltPatternParser (System.Xml.Xsl.IStaticXsltContext context)
  31. #else
  32. public XPathParser () : this (null) {}
  33. internal XPathParser (System.Xml.Xsl.IStaticXsltContext context)
  34. #endif
  35. {
  36. Context = context;
  37. ErrorOutput = System.IO.TextWriter.Null;
  38. // debug = new yydebug.yyDebugSimple ();
  39. }
  40. internal Expression Compile (string xpath)
  41. {
  42. try {
  43. Tokenizer tokenizer = new Tokenizer (xpath);
  44. return (Expression) yyparse (tokenizer);
  45. } catch (XPathException) {
  46. throw;
  47. } catch (Exception e) {
  48. throw new XPathException ("Error during parse of " + xpath, e);
  49. }
  50. }
  51. static int yacc_verbose_flag;
  52. private NodeSet CreateNodeTest (Axes axis, object nodeTest, ArrayList plist)
  53. {
  54. NodeSet test = CreateNodeTest (axis, nodeTest);
  55. if (plist != null) {
  56. for (int i = 0; i < plist.Count; i++)
  57. test = new ExprFilter (test,
  58. (Expression) plist [i]);
  59. }
  60. return test;
  61. }
  62. private NodeTest CreateNodeTest (Axes axis, object test)
  63. {
  64. if (test is XPathNodeType)
  65. return new NodeTypeTest (axis,
  66. (XPathNodeType) test, null);
  67. else if (test is string || test == null)
  68. return new NodeTypeTest (axis,
  69. XPathNodeType.ProcessingInstruction,
  70. (string) test);
  71. XmlQualifiedName q = (XmlQualifiedName) test;
  72. if (q == XmlQualifiedName.Empty)
  73. return new NodeTypeTest (axis);
  74. else
  75. return new NodeNameTest (axis, q, Context);
  76. }
  77. %}
  78. %token ERROR
  79. %token EOF
  80. %token SLASH "/"
  81. %token SLASH2 "//"
  82. %token DOT "."
  83. %token DOT2 ".."
  84. %token COLON2 "::"
  85. %token COMMA ","
  86. %token AT "@"
  87. %token FUNCTION_NAME
  88. %token BRACKET_OPEN "["
  89. %token BRACKET_CLOSE "]"
  90. %token PAREN_OPEN "("
  91. %token PAREN_CLOSE ")"
  92. %token AND "and"
  93. %token OR "or"
  94. %token DIV "div"
  95. %token MOD "mod"
  96. %token PLUS "+"
  97. %token MINUS "-"
  98. %token ASTERISK "*"
  99. %token DOLLAR "$"
  100. %token BAR "|"
  101. %token EQ "="
  102. %token NE "!="
  103. %token LE "<="
  104. %token GE ">="
  105. %token LT "<"
  106. %token GT ">"
  107. %token ANCESTOR "ancestor"
  108. %token ANCESTOR_OR_SELF "ancstor-or-self"
  109. %token ATTRIBUTE "attribute"
  110. %token CHILD "child"
  111. %token DESCENDANT "descendant"
  112. %token DESCENDANT_OR_SELF "descendant-or-self"
  113. %token FOLLOWING "following"
  114. %token FOLLOWING_SIBLING "sibling"
  115. %token NAMESPACE "NameSpace"
  116. %token PARENT "parent"
  117. %token PRECEDING "preceding"
  118. %token PRECEDING_SIBLING "preceding-sibling"
  119. %token SELF "self"
  120. %token COMMENT "comment"
  121. %token TEXT "text"
  122. %token PROCESSING_INSTRUCTION "processing-instruction"
  123. %token NODE "node"
  124. %token MULTIPLY "*"
  125. %token NUMBER
  126. %token LITERAL
  127. %token QName
  128. %start Expr
  129. %left AND
  130. %left OR
  131. %left EQ
  132. %left NE
  133. %left LE
  134. %left GE
  135. %left LT
  136. %left GT
  137. %left DIV
  138. %left MOD
  139. %left PLUS
  140. %left MINUS
  141. %%
  142. /* XSLT Pattern */
  143. Pattern
  144. : LocationPathPattern
  145. | Pattern BAR LocationPathPattern
  146. {
  147. $$ = new ExprUNION ((NodeSet) $1, (NodeSet) $3);
  148. }
  149. ;
  150. LocationPathPattern
  151. : SLASH
  152. {
  153. $$ = new ExprRoot ();
  154. }
  155. | SLASH RelativePathPattern
  156. {
  157. $$ = new ExprSLASH (new ExprRoot (), (NodeSet) $2);
  158. }
  159. | IdKeyPattern
  160. | IdKeyPattern SLASH RelativePathPattern
  161. {
  162. $$ = new ExprSLASH ((Expression) $1, (NodeSet) $3);
  163. }
  164. | IdKeyPattern SLASH2 RelativePathPattern
  165. {
  166. $$ = new ExprSLASH2 ((Expression) $1, (NodeSet) $3);
  167. }
  168. | SLASH2 RelativePathPattern
  169. {
  170. $$ = new ExprSLASH2 (new ExprRoot (), (NodeSet) $2);
  171. }
  172. | RelativePathPattern
  173. ;
  174. // to avoid context-sensitive tokenizer, I just reuse FUNCTION_NAME
  175. IdKeyPattern
  176. : FUNCTION_NAME PAREN_OPEN LITERAL PAREN_CLOSE
  177. {
  178. XmlQualifiedName name = (XmlQualifiedName) $1;
  179. if (name.Name != "id" || name.Namespace != String.Empty)
  180. throw new XPathException (String.Format ("Expected 'id' but got '{0}'", name));
  181. $$ = ExprFunctionCall.Factory (name,
  182. new FunctionArguments (
  183. new ExprLiteral ((string) $3),
  184. null),
  185. Context);
  186. }
  187. | FUNCTION_NAME PAREN_OPEN LITERAL COMMA LITERAL PAREN_CLOSE
  188. {
  189. XmlQualifiedName name = (XmlQualifiedName) $1;
  190. if (name.Name != "key" || name.Namespace != String.Empty)
  191. throw new XPathException (String.Format ("Expected 'key' but got '{0}'", name));
  192. $$ = Context.TryGetFunction (name,
  193. new FunctionArguments (
  194. new ExprLiteral ((string) $3),
  195. new FunctionArguments (
  196. new ExprLiteral ((string) $5),
  197. null)));
  198. }
  199. ;
  200. RelativePathPattern
  201. : StepPattern
  202. | RelativePathPattern SLASH StepPattern
  203. {
  204. $$ = new ExprSLASH ((Expression) $1, (NodeSet) $3);
  205. }
  206. | RelativePathPattern SLASH2 StepPattern
  207. {
  208. $$ = new ExprSLASH2 ((Expression) $1, (NodeSet) $3);
  209. }
  210. ;
  211. StepPattern
  212. : ChildOrAttributeAxisSpecifier NodeTest Predicates
  213. {
  214. $$ = CreateNodeTest ((Axes) $1, $2, (ArrayList) $3);
  215. }
  216. ;
  217. ChildOrAttributeAxisSpecifier
  218. : AbbreviatedAxisSpecifier
  219. | CHILD COLON2
  220. {
  221. $$ = Axes.Child;
  222. }
  223. | ATTRIBUTE COLON2
  224. {
  225. $$ = Axes.Attribute;
  226. }
  227. ;
  228. Predicates
  229. : // empty
  230. {
  231. $$ = null;
  232. }
  233. | Predicates Predicate
  234. {
  235. ArrayList al = (ArrayList) $1;
  236. if (al == null)
  237. al = new ArrayList ();
  238. al.Add ((Expression) $2);
  239. $$ = al;
  240. }
  241. ;
  242. /* ---- end of XSLT Pattern ---- */
  243. Expr
  244. : OrExpr
  245. ;
  246. OrExpr
  247. : AndExpr
  248. | OrExpr OR AndExpr
  249. {
  250. $$ = new ExprOR ((Expression) $1, (Expression) $3);
  251. }
  252. ;
  253. AndExpr
  254. : EqualityExpr
  255. | AndExpr AND EqualityExpr
  256. {
  257. $$ = new ExprAND ((Expression) $1, (Expression) $3);
  258. }
  259. ;
  260. EqualityExpr
  261. : RelationalExpr
  262. | EqualityExpr EQ RelationalExpr
  263. {
  264. $$ = new ExprEQ ((Expression) $1, (Expression) $3);
  265. }
  266. | EqualityExpr NE RelationalExpr
  267. {
  268. $$ = new ExprNE ((Expression) $1, (Expression) $3);
  269. }
  270. ;
  271. RelationalExpr
  272. : AdditiveExpr
  273. | RelationalExpr LT AdditiveExpr
  274. {
  275. $$ = new ExprLT ((Expression) $1, (Expression) $3);
  276. }
  277. | RelationalExpr GT AdditiveExpr
  278. {
  279. $$ = new ExprGT ((Expression) $1, (Expression) $3);
  280. }
  281. | RelationalExpr LE AdditiveExpr
  282. {
  283. $$ = new ExprLE ((Expression) $1, (Expression) $3);
  284. }
  285. | RelationalExpr GE AdditiveExpr
  286. {
  287. $$ = new ExprGE ((Expression) $1, (Expression) $3);
  288. }
  289. ;
  290. AdditiveExpr
  291. : MultiplicativeExpr
  292. | AdditiveExpr PLUS MultiplicativeExpr
  293. {
  294. $$ = new ExprPLUS ((Expression) $1, (Expression) $3);
  295. }
  296. | AdditiveExpr MINUS MultiplicativeExpr
  297. {
  298. $$ = new ExprMINUS ((Expression) $1, (Expression) $3);
  299. }
  300. ;
  301. MultiplicativeExpr
  302. : UnaryExpr
  303. | MultiplicativeExpr MULTIPLY UnaryExpr
  304. {
  305. $$ = new ExprMULT ((Expression) $1, (Expression) $3);
  306. }
  307. | MultiplicativeExpr DIV UnaryExpr
  308. {
  309. $$ = new ExprDIV ((Expression) $1, (Expression) $3);
  310. }
  311. | MultiplicativeExpr MOD UnaryExpr
  312. {
  313. $$ = new ExprMOD ((Expression) $1, (Expression) $3);
  314. }
  315. ;
  316. UnaryExpr
  317. : UnionExpr
  318. | MINUS UnaryExpr
  319. {
  320. $$ = new ExprNEG ((Expression) $2);
  321. }
  322. ;
  323. UnionExpr
  324. : PathExpr
  325. | UnionExpr BAR PathExpr
  326. {
  327. $$ = new ExprUNION ((Expression) $1, (Expression) $3);
  328. }
  329. ;
  330. PathExpr
  331. : LocationPath
  332. | FilterExpr
  333. | FilterExpr SLASH RelativeLocationPath
  334. {
  335. $$ = new ExprSLASH ((Expression) $1, (NodeSet) $3);
  336. }
  337. | FilterExpr SLASH2 RelativeLocationPath
  338. {
  339. $$ = new ExprSLASH2 ((Expression) $1, (NodeSet) $3);
  340. }
  341. ;
  342. LocationPath
  343. : RelativeLocationPath
  344. | AbsoluteLocationPath
  345. ;
  346. AbsoluteLocationPath
  347. : SLASH
  348. {
  349. $$ = new ExprRoot ();
  350. }
  351. | SLASH RelativeLocationPath
  352. {
  353. $$ = new ExprSLASH (new ExprRoot (), (NodeSet) $2);
  354. }
  355. | SLASH2 RelativeLocationPath
  356. {
  357. $$ = new ExprSLASH2 (new ExprRoot (), (NodeSet) $2);
  358. }
  359. ;
  360. RelativeLocationPath
  361. : Step
  362. | RelativeLocationPath SLASH Step
  363. {
  364. $$ = new ExprSLASH ((NodeSet) $1, (NodeSet) $3);
  365. }
  366. | RelativeLocationPath SLASH2 Step
  367. {
  368. $$ = new ExprSLASH2 ((NodeSet) $1, (NodeSet) $3);
  369. }
  370. ;
  371. Step
  372. : AxisSpecifier NodeTest Predicates
  373. {
  374. $$ = CreateNodeTest ((Axes) $1, $2, (ArrayList) $3);
  375. }
  376. | AbbreviatedStep
  377. ;
  378. NodeTest // QName, XPathNodeType or string
  379. : NameTest
  380. | NodeType PAREN_OPEN PAREN_CLOSE
  381. {
  382. $$ = (XPathNodeType) $1;
  383. }
  384. | PROCESSING_INSTRUCTION PAREN_OPEN OptionalLiteral PAREN_CLOSE
  385. {
  386. $$ = (string) $3;
  387. }
  388. ;
  389. NameTest
  390. : ASTERISK
  391. {
  392. $$ = XmlQualifiedName.Empty;
  393. }
  394. | QName // token QName also contains "blah:*"
  395. ;
  396. AbbreviatedStep
  397. : DOT
  398. {
  399. $$ = new NodeTypeTest (Axes.Self, XPathNodeType.All);
  400. }
  401. | DOT2
  402. {
  403. $$ = new NodeTypeTest (Axes.Parent, XPathNodeType.All);
  404. }
  405. ;
  406. Predicates
  407. : /* empty */
  408. {
  409. $$ = null;
  410. }
  411. | Predicates Predicate
  412. {
  413. ArrayList al = (ArrayList) $1;
  414. if (al == null)
  415. al = new ArrayList ();
  416. al.Add ($2);
  417. $$ = al;
  418. }
  419. ;
  420. AxisSpecifier
  421. : AxisName COLON2
  422. {
  423. $$ = $1;
  424. }
  425. | AbbreviatedAxisSpecifier
  426. ;
  427. AbbreviatedAxisSpecifier
  428. : /* empty */
  429. {
  430. $$ = Axes.Child;
  431. }
  432. | AT
  433. {
  434. $$ = Axes.Attribute;
  435. }
  436. ;
  437. NodeType
  438. : COMMENT { $$ = XPathNodeType.Comment; }
  439. | TEXT { $$ = XPathNodeType.Text; }
  440. | PROCESSING_INSTRUCTION { $$ = XPathNodeType.ProcessingInstruction; }
  441. | NODE { $$ = XPathNodeType.All; }
  442. ;
  443. FilterExpr
  444. : PrimaryExpr
  445. | FilterExpr Predicate
  446. {
  447. $$ = new ExprFilter ((Expression) $1, (Expression) $2);
  448. }
  449. ;
  450. PrimaryExpr
  451. : DOLLAR QName
  452. {
  453. Expression ret = null;
  454. if (Context != null)
  455. ret = Context.TryGetVariable (((XmlQualifiedName) $2).ToString ());
  456. if (ret == null)
  457. ret = new ExprVariable ((XmlQualifiedName) $2, Context);
  458. $$ = ret;
  459. }
  460. | PAREN_OPEN Expr PAREN_CLOSE
  461. {
  462. $$ = new ExprParens ((Expression) $2);
  463. }
  464. | LITERAL
  465. {
  466. $$ = new ExprLiteral ((String) $1);
  467. }
  468. | NUMBER
  469. {
  470. $$ = new ExprNumber ((double) $1);
  471. }
  472. | FunctionCall
  473. ;
  474. FunctionCall
  475. : FUNCTION_NAME PAREN_OPEN OptionalArgumentList PAREN_CLOSE
  476. {
  477. Expression ret = null;
  478. if (Context != null)
  479. ret = Context.TryGetFunction ((XmlQualifiedName) $1, (FunctionArguments) $3);
  480. if (ret == null)
  481. ret = ExprFunctionCall.Factory ((XmlQualifiedName) $1, (FunctionArguments) $3, Context);
  482. $$ = ret;
  483. }
  484. ;
  485. OptionalArgumentList
  486. : /* empty */
  487. | Expr OptionalArgumentListTail
  488. {
  489. $$ = new FunctionArguments ((Expression) $1, (FunctionArguments) $2);
  490. }
  491. ;
  492. OptionalArgumentListTail
  493. : /* empty */
  494. | COMMA Expr OptionalArgumentListTail
  495. {
  496. $$ = new FunctionArguments ((Expression) $2, (FunctionArguments) $3);
  497. }
  498. ;
  499. Predicate
  500. : BRACKET_OPEN Expr BRACKET_CLOSE
  501. {
  502. $$ = $2;
  503. }
  504. ;
  505. AxisName
  506. : ANCESTOR { $$ = Axes.Ancestor; }
  507. | ANCESTOR_OR_SELF { $$ = Axes.AncestorOrSelf; }
  508. | ATTRIBUTE { $$ = Axes.Attribute; }
  509. | CHILD { $$ = Axes.Child; }
  510. | DESCENDANT { $$ = Axes.Descendant; }
  511. | DESCENDANT_OR_SELF { $$ = Axes.DescendantOrSelf; }
  512. | FOLLOWING { $$ = Axes.Following; }
  513. | FOLLOWING_SIBLING { $$ = Axes.FollowingSibling; }
  514. | NAMESPACE { $$ = Axes.Namespace; }
  515. | PARENT { $$ = Axes.Parent; }
  516. | PRECEDING { $$ = Axes.Preceding; }
  517. | PRECEDING_SIBLING { $$ = Axes.PrecedingSibling; }
  518. | SELF { $$ = Axes.Self; }
  519. ;
  520. OptionalLiteral
  521. : /* empty */
  522. | LITERAL
  523. ;
  524. %%
  525. }