/parser.y

http://github.com/fizx/parsley · Happy · 631 lines · 560 code · 71 blank · 0 comment · 0 complexity · ab793a8be436f7468091ecda3d0df141 MD5 · raw file

  1. %{
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "parsed_xpath.h"
  7. #include <libxml/hash.h>
  8. #ifndef PARSER_Y_H_INCLUDED
  9. #define PARSER_Y_H_INCLUDED
  10. static pxpathPtr parsed_answer;
  11. int yylex (void);
  12. void yyerror (char const *);
  13. void prepare_parse(char*);
  14. void cleanup_parse(void);
  15. void start_debugging(void);
  16. static xmlHashTablePtr alias_hash;
  17. char* xpath_alias(char*);
  18. void init_xpath_alias();
  19. int yyparse(void);
  20. pxpathPtr myparse(char*);
  21. void answer(pxpathPtr);
  22. #define LIT_BIN_OP(A, B, C) pxpath_cat_literals(3, A, LIT(B), C)
  23. #define BIN_OP(A, B, C) pxpath_cat_paths(3, A, OP(B), C)
  24. #define PREP_OP(A, B) pxpath_cat_paths(2, OP(A), B)
  25. #define PXP(A) pxpath_new_path(1, A)
  26. #define LIT(A) pxpath_new_literal(1, A)
  27. #define OP(A) pxpath_new_operator(1, A)
  28. #define APPEND(A, S) pxpath_cat_paths(2, A, PXP(S));
  29. #define PREPEND(A, S) pxpath_cat_paths(2, PXP(S), A);
  30. #define PXPWRAP(A, B, C) pxpath_cat_paths(3, PXP(A), B, PXP(C))
  31. #define P4E(A, B, C, D) pxpath_cat_paths(4, A, PXP(B), C, PXP(D))
  32. #define P4O(A, B, C, D) pxpath_cat_paths(4, PXP(A), B, PXP(C), D)
  33. #define P6E(A, B, C, D, E, F) pxpath_cat_paths(6, A, PXP(B), C, PXP(D), E, PXP(F));
  34. #define INPUT_TYPE(A, S) APPEND(A, "[lower-case(name())='input' and lower-case(@type)='" #S "']")
  35. #define TRACE(A, B) fprintf(stderr, "trace(%s): ", A); fprintf(stderr, "%s\n", pxpath_to_string(B));
  36. #endif
  37. %}
  38. %glr-parser
  39. %token_table
  40. %debug
  41. %union {
  42. int empty;
  43. char* string;
  44. pxpathPtr node;
  45. }
  46. %token <string> NUMBER
  47. %token <string> S
  48. %token <string> AT
  49. %token <string> LPAREN
  50. %token <string> RPAREN
  51. %token <string> PIPE
  52. %token <string> LT
  53. %token <string> SLASH
  54. %token <string> DBLSLASH
  55. %token <string> BANG
  56. %token <string> COLON
  57. %token <string> DBLCOLON
  58. %token <string> QUERY
  59. %token <string> HASH
  60. %token <string> COMMA
  61. %token <string> DOT
  62. %token <string> DBLDOT
  63. %token <string> GT
  64. %token <string> LBRA
  65. %token <string> RBRA
  66. %token <string> TILDE
  67. %token <string> SPLAT
  68. %token <string> PLUS
  69. %token <string> DASH
  70. %token <string> EQ
  71. %token <string> LTE
  72. %token <string> GTE
  73. %token <string> DOLLAR
  74. %token <string> BSLASHLIT
  75. %token <string> OTHER
  76. %token <string> XANCESTOR
  77. %token <string> XANCESTORSELF
  78. %token <string> XATTR
  79. %token <string> XCHILD
  80. %token <string> XDESC
  81. %token <string> XDESCSELF
  82. %token <string> XFOLLOW
  83. %token <string> XFOLLOWSIB
  84. %token <string> XNS
  85. %token <string> XPARENT
  86. %token <string> XPRE
  87. %token <string> XPRESIB
  88. %token <string> XSELF
  89. %token <string> XOR
  90. %token <string> XAND
  91. %token <string> XDIV
  92. %token <string> XMOD
  93. %token <string> XCOMMENT
  94. %token <string> XTEXT
  95. %token <string> XPI
  96. %token <string> XNODE
  97. %token <string> CXEQUATION
  98. %token <string> CXOPHE
  99. %token <string> CXOPNE
  100. %token <string> CXOPSTARTEQ
  101. %token <string> CXOPENDEQ
  102. %token <string> CXOPCONTAINS
  103. %token <string> CXOPCONTAINS2
  104. %token <string> CXFIRST
  105. %token <string> CXLAST
  106. %token <string> CXNOT
  107. %token <string> CXEVEN
  108. %token <string> CXODD
  109. %token <string> CXEQ
  110. %token <string> CXGT
  111. %token <string> CXLT
  112. %token <string> CXCONTENT
  113. %token <string> CXHEADER
  114. %token <string> CXCONTAINS
  115. %token <string> CXEMPTY
  116. %token <string> CXHAS
  117. %token <string> CXPARENT
  118. %token <string> CXNTHCH
  119. %token <string> CXNTHLASTCH
  120. %token <string> CXNTHTYPE
  121. %token <string> CXNTHLASTTYPE
  122. %token <string> CXFIRSTCH
  123. %token <string> CXLASTCH
  124. %token <string> CXFIRSTTYPE
  125. %token <string> CXLASTTYPE
  126. %token <string> CXONLYCH
  127. %token <string> CXONLYTYPE
  128. %token <string> CXINPUT
  129. %token <string> CXTEXT
  130. %token <string> CXPASSWORD
  131. %token <string> CXRADIO
  132. %token <string> CXCHECKBOX
  133. %token <string> CXSUBMIT
  134. %token <string> CXIMAGE
  135. %token <string> CXRESET
  136. %token <string> CXBUTTON
  137. %token <string> CXFILE
  138. %token <string> CXENABLED
  139. %token <string> CXDISABLED
  140. %token <string> CXCHECKED
  141. %token <string> CXSELECTED
  142. %token <string> NAME
  143. %token <string> STRING
  144. %type <node> Root
  145. %type <empty> OptS
  146. %type <node> LocationPath
  147. %type <node> AbsoluteLocationPath
  148. %type <node> RelativeLocationPath
  149. %type <node> Step
  150. %type <node> AxisSpecifier
  151. %type <string> AxisName
  152. %type <node> NodeTest
  153. %type <node> Predicates
  154. %type <node> Predicate
  155. %type <node> PredicateExpr
  156. %type <node> AbbreviatedAbsoluteLocationPath
  157. %type <node> AbbreviatedRelativeLocationPath
  158. %type <string> AbbreviatedStep
  159. %type <string> AbbreviatedAxisSpecifier
  160. %type <node> Expr
  161. %type <node> NumberLike
  162. %type <node> PrimaryExpr
  163. %type <node> FunctionCall
  164. %type <node> Arguments
  165. %type <node> ArgumentSet
  166. %type <node> PrefixedName
  167. %type <node> Argument
  168. %type <node> UnionExpr
  169. %type <node> PathExpr
  170. %type <node> FunctionName
  171. %type <node> FilterExpr
  172. %type <node> OrExpr
  173. %type <node> AndExpr
  174. %type <node> EqualityExpr
  175. %type <node> RelationalExpr
  176. %type <node> AdditiveExpr
  177. %type <node> MultiplicativeExpr
  178. %type <node> UnaryExpr
  179. %type <string> Literal
  180. %type <node> Number
  181. %type <node> simple_selector_anchor
  182. %type <string> MultiplyOperator
  183. %type <node> VariableReference
  184. %type <node> NameTest
  185. %type <string> NodeType
  186. %type <string> UnprefixedName
  187. %type <string> combinator
  188. %type <node> possibly_empty_sequence
  189. %type <string> keyword
  190. %type <node> StringLike
  191. %type <node> selectors_group
  192. %type <node> QName
  193. %type <string> NCName
  194. %type <string> Prefix
  195. %type <string> LocalPart
  196. %type <node> attribute_extended_selector
  197. %type <node> Ident
  198. %type <node> universal
  199. %type <node> selector
  200. %type <node> namespace_prefix
  201. %type <node> type_selector
  202. %type <node> element_name
  203. %type <node> simple_selector_sequence
  204. %%
  205. Root
  206. : Expr OptS { answer($1); }
  207. ;
  208. LocationPath
  209. : RelativeLocationPath %dprec 1
  210. | AbsoluteLocationPath %dprec 2
  211. | selectors_group %dprec 3
  212. ;
  213. AbsoluteLocationPath
  214. : SLASH RelativeLocationPath { $$ = PREP_OP($1, $2); }
  215. | SLASH { $$ = PXP($1); }
  216. | AbbreviatedAbsoluteLocationPath
  217. ;
  218. RelativeLocationPath
  219. : Step
  220. | RelativeLocationPath SLASH Step { $$ = BIN_OP($1, $2, $3); }
  221. | AbbreviatedRelativeLocationPath
  222. ;
  223. Step
  224. : AxisSpecifier NodeTest { $$ = pxpath_cat_paths(2, $1, $2); }
  225. | AxisSpecifier NodeTest Predicates { $$ = pxpath_cat_paths(3, $1, $2, $3); }
  226. | AbbreviatedStep { $$ = PXP($1); }
  227. ;
  228. AxisSpecifier
  229. : AxisName DBLCOLON { $$ = pxpath_new_path(2, $1, $2); }
  230. | AbbreviatedAxisSpecifier { $$ = PXP($1); }
  231. ;
  232. AxisName
  233. : XANCESTOR
  234. | XANCESTORSELF
  235. | XATTR
  236. | XCHILD
  237. | XDESC
  238. | XDESCSELF
  239. | XFOLLOW
  240. | XFOLLOWSIB
  241. | XNS
  242. | XPARENT
  243. | XPRE
  244. | XPRESIB
  245. | XSELF
  246. ;
  247. NodeTest
  248. : NameTest
  249. | NodeType LPAREN RPAREN { $$ = pxpath_new_path(3, $1, $2, $3); }
  250. | XPI LPAREN Literal RPAREN { $$ = pxpath_new_path(4, $1, $2, $3, $4); }
  251. ;
  252. Predicates
  253. : Predicates Predicate { $$ = pxpath_cat_paths(2, $1, $2); }
  254. | Predicate
  255. ;
  256. Predicate
  257. : LBRA PredicateExpr RBRA { $$ = PXPWRAP($1, $2, $3); }
  258. ;
  259. PredicateExpr
  260. : Expr
  261. ;
  262. AbbreviatedAbsoluteLocationPath
  263. : DBLSLASH RelativeLocationPath { $$ = PREP_OP($1, $2); }
  264. ;
  265. AbbreviatedRelativeLocationPath
  266. : RelativeLocationPath DBLSLASH Step { $$ = BIN_OP($1, $2, $3); }
  267. ;
  268. AbbreviatedStep
  269. : DOT
  270. | DBLDOT
  271. ;
  272. AbbreviatedAxisSpecifier
  273. : AT
  274. | { $$ = ""; }
  275. ;
  276. Expr
  277. : LPAREN Argument RPAREN %dprec 2 { $$ = PXPWRAP($1, $2, $3); }
  278. | OrExpr %dprec 1
  279. ;
  280. PrimaryExpr
  281. : VariableReference
  282. | LPAREN Expr RPAREN { $$ = PXPWRAP($1, $2, $3); }
  283. | Literal { $$ = LIT($1); }
  284. | Number
  285. | FunctionCall
  286. ;
  287. FunctionCall
  288. : FunctionName LPAREN Arguments RPAREN { $$ = pxpath_new_func(xpath_alias(pxpath_to_string($1)), $3); }
  289. ;
  290. Arguments
  291. : ArgumentSet
  292. | { $$ = NULL; }
  293. ;
  294. ArgumentSet
  295. : Argument COMMA ArgumentSet %dprec 2 { $$ = $1; $1->next = $3; }
  296. | Argument %dprec 1
  297. ;
  298. Argument
  299. : OptS Expr OptS { $$ = $2; }
  300. ;
  301. UnionExpr
  302. : PathExpr
  303. | UnionExpr PIPE PathExpr { $$ = BIN_OP($1, $2, $3); }
  304. ;
  305. PathExpr
  306. : LocationPath
  307. | FilterExpr
  308. | FilterExpr SLASH RelativeLocationPath { $$ = BIN_OP($1, $2, $3); }
  309. | FilterExpr DBLSLASH RelativeLocationPath { $$ = BIN_OP($1, $2, $3); }
  310. ;
  311. FilterExpr
  312. : PrimaryExpr
  313. | FilterExpr Predicates { $$ = pxpath_cat_paths(2, $1, $2); }
  314. ;
  315. OrExpr
  316. : AndExpr
  317. | OrExpr XOR AndExpr { $$ = LIT_BIN_OP($1, $2, $3); }
  318. ;
  319. AndExpr
  320. : EqualityExpr
  321. | AndExpr XAND EqualityExpr { $$ = LIT_BIN_OP($1, $2, $3); }
  322. ;
  323. EqualityExpr
  324. : RelationalExpr
  325. | EqualityExpr EQ RelationalExpr { $$ = LIT_BIN_OP($1, $2, $3); }
  326. | EqualityExpr CXOPNE RelationalExpr { $$ = LIT_BIN_OP($1, $2, $3); }
  327. ;
  328. RelationalExpr
  329. : AdditiveExpr %dprec 2
  330. | RelationalExpr OptS LT OptS AdditiveExpr %dprec 3 { $$ = LIT_BIN_OP($1, $3, $5); }
  331. | RelationalExpr OptS GT OptS AdditiveExpr %dprec 1 { $$ = LIT_BIN_OP($1, $3, $5); }
  332. | RelationalExpr OptS LTE OptS AdditiveExpr %dprec 3 { $$ = LIT_BIN_OP($1, $3, $5); }
  333. | RelationalExpr OptS GTE OptS AdditiveExpr %dprec 3 { $$ = LIT_BIN_OP($1, $3, $5); }
  334. ;
  335. AdditiveExpr
  336. : MultiplicativeExpr %dprec 3
  337. | AdditiveExpr OptS PLUS OptS MultiplicativeExpr %dprec 1 { $$ = LIT_BIN_OP($1, $3, $5); }
  338. | AdditiveExpr OptS DASH OptS MultiplicativeExpr %dprec 2 { $$ = LIT_BIN_OP($1, $3, $5); }
  339. ;
  340. MultiplicativeExpr
  341. : UnaryExpr %dprec 2
  342. | MultiplicativeExpr OptS MultiplyOperator OptS UnaryExpr %dprec 2 { $$ = LIT_BIN_OP($1, $3, $5); }
  343. | MultiplicativeExpr OptS XDIV OptS UnaryExpr %dprec 1 { $$ = LIT_BIN_OP($1, $3, $5); }
  344. | MultiplicativeExpr OptS XMOD OptS UnaryExpr %dprec 2 { $$ = LIT_BIN_OP($1, $3, $5); }
  345. ;
  346. UnaryExpr
  347. : UnionExpr
  348. | DASH UnaryExpr { $$ = PREP_OP($1, $2); }
  349. ;
  350. Literal
  351. : STRING
  352. ;
  353. Number
  354. : NUMBER { $$ = LIT($1); }
  355. | NUMBER DOT { $$ = pxpath_new_literal(2, $1, $2); }
  356. | NUMBER DOT NUMBER { $$ = pxpath_new_literal(3, $1, $2, $3); }
  357. | DOT NUMBER { $$ = pxpath_new_literal(2, $1, $2); }
  358. ;
  359. MultiplyOperator
  360. : SPLAT
  361. ;
  362. VariableReference
  363. : DOLLAR QName { $$ = PREP_OP($1, $2); }
  364. ;
  365. NameTest
  366. : SPLAT { $$ = PXP($1); }
  367. | NCName COLON SPLAT { $$ = pxpath_new_path(3, $1, $2, $3); }
  368. | QName
  369. ;
  370. NodeType
  371. : XCOMMENT
  372. | XTEXT
  373. | XPI
  374. | XNODE
  375. ;
  376. FunctionName
  377. : QName
  378. ;
  379. QName
  380. : PrefixedName
  381. | UnprefixedName { $$ = PXP($1); }
  382. ;
  383. PrefixedName
  384. : Prefix COLON LocalPart { $$ = pxpath_new_path(3, $1, $2, $3); }
  385. ;
  386. UnprefixedName
  387. : LocalPart
  388. ;
  389. Prefix
  390. : NCName
  391. ;
  392. LocalPart
  393. : NCName
  394. ;
  395. NCName
  396. : NAME
  397. | keyword
  398. ;
  399. selectors_group
  400. : attribute_extended_selector COMMA OptS selectors_group { $$ = pxpath_cat_paths(4, pxpath_new_literal(1, ".//"), $1, pxpath_new_literal(1, "|"), $4); }
  401. | attribute_extended_selector { $$ = pxpath_cat_paths(2, pxpath_new_literal(1, ".//"), $1); }
  402. ;
  403. attribute_extended_selector
  404. : selector
  405. | selector S AT NAME { $$ = pxpath_cat_paths(3, $1, PXP("/@"), PXP($4)); }
  406. ;
  407. selector
  408. : simple_selector_sequence combinator selector { $$ = pxpath_cat_paths(3, $1, PXP($2), $3); }
  409. | simple_selector_sequence
  410. ;
  411. combinator
  412. : OptS PLUS OptS { $$ = "/following-sibling::*[1]/self::"; }
  413. | OptS GT OptS { $$ = "/"; }
  414. | OptS TILDE OptS { $$ = "/following-sibling::*/self::"; }
  415. | S { $$ = "//"; }
  416. ;
  417. simple_selector_sequence
  418. : simple_selector_anchor
  419. | possibly_empty_sequence LBRA type_selector OptS CXOPHE OptS StringLike OptS RBRA { $$ = pxpath_cat_paths(10, $1, PXP("[@"), $3, PXP(" = "), $7, PXP(" or starts-with(@"), $3, PXP(", concat("), $7, PXP(", '-' ))]")); }
  420. | possibly_empty_sequence CXNOT LPAREN selectors_group RPAREN { $$ = pxpath_cat_paths(5, PXP("set-difference("), $1, PXP(", "), $4, PXP(")")); }
  421. | possibly_empty_sequence HASH Ident { $$ = P4E($1, "[@id='", $3, "']"); }
  422. | possibly_empty_sequence DOT Ident { $$ = P4E($1, "[contains(concat( ' ', @class, ' ' ), concat( ' ', '", $3, "', ' ' ))]"); }
  423. | possibly_empty_sequence LBRA type_selector RBRA { $$ = P4E($1, "[@", $3, "]"); }
  424. | possibly_empty_sequence CXEQ LPAREN NumberLike RPAREN { $$ = P4E($1, "[position() = ", $3, "]"); }
  425. | possibly_empty_sequence CXGT LPAREN NumberLike RPAREN { $$ = P4E($1, "[position() > ", $3, "]"); }
  426. | possibly_empty_sequence CXLT LPAREN NumberLike RPAREN { $$ = P4E($1, "[position() < ", $3, "]"); }
  427. | possibly_empty_sequence CXCONTAINS LPAREN StringLike RPAREN { $$ = P4E($1, "[contains(., ", $4, ")]"); }
  428. | possibly_empty_sequence CXHAS LPAREN selectors_group RPAREN { $$ = P4E($1, "[", $3, "]"); }
  429. | possibly_empty_sequence CXNTHTYPE LPAREN NumberLike RPAREN { $$ = P4E($1, "[position() = ", $3, "]"); }
  430. | possibly_empty_sequence CXNTHLASTTYPE LPAREN NumberLike RPAREN { $$ = P4E($1, "[position() = last() - ", $3, "]"); }
  431. | possibly_empty_sequence LBRA type_selector OptS EQ OptS StringLike OptS RBRA { $$ = P6E($1, "[@", $3, " = ", $7, "]"); }
  432. | possibly_empty_sequence LBRA type_selector OptS CXOPNE OptS StringLike OptS RBRA { $$ = P6E($1, "[@", $3, " != ", $7, "]"); }
  433. | possibly_empty_sequence LBRA type_selector OptS CXOPSTARTEQ OptS StringLike OptS RBRA { $$ = P6E($1, "[starts-with(@", $3, ", ", $7, ")]"); }
  434. | possibly_empty_sequence LBRA type_selector OptS CXOPENDEQ OptS StringLike OptS RBRA { $$ = P6E($1, "[ends-with(@", $3, ", ", $7, ")]"); }
  435. | possibly_empty_sequence LBRA type_selector OptS CXOPCONTAINS OptS StringLike OptS RBRA { $$ = P6E($1, "[contains(@", $3, ", ", $7, ")]"); }
  436. | possibly_empty_sequence LBRA type_selector OptS CXOPCONTAINS2 OptS StringLike OptS RBRA { $$ = P6E($1, "[contains(@", $3, ", ", $7, ")]"); }
  437. | possibly_empty_sequence CXNTHCH LPAREN NumberLike RPAREN { $$ = P4O("*[", $4, "]/self::", $1); }
  438. | possibly_empty_sequence CXNTHLASTCH LPAREN NumberLike RPAREN { $$ = P4O("*[last() - ", $4, "]/self::", $1); }
  439. | possibly_empty_sequence CXFIRST { $$ = APPEND($1, "[1]"); }
  440. | possibly_empty_sequence CXLAST { $$ = APPEND($1, "[last()]"); }
  441. | possibly_empty_sequence CXEVEN { $$ = APPEND($1, "[position() % 2 = 0]"); }
  442. | possibly_empty_sequence CXODD { $$ = APPEND($1, "[position() % 2 = 1]"); }
  443. | possibly_empty_sequence CXCONTENT LPAREN StringLike RPAREN { $$ = P4E($1, "[translate(normalize-space(.), $nbsp, ' ')=", $4, "]"); }
  444. | possibly_empty_sequence CXHEADER { $$ = APPEND($1, "[contains('h1 h2 h3 h4 h5 h6', lower-case(local-name()))]"); }
  445. | possibly_empty_sequence CXEMPTY { $$ = APPEND($1, "[not(node())]"); }
  446. | possibly_empty_sequence CXPARENT { $$ = APPEND($1, "[node()]"); }
  447. | possibly_empty_sequence CXFIRSTTYPE { $$ = APPEND($1, "[1]"); }
  448. | possibly_empty_sequence CXLASTTYPE { $$ = APPEND($1, "[last()]"); }
  449. | possibly_empty_sequence CXONLYTYPE { $$ = APPEND($1, "[count()=1]"); }
  450. | possibly_empty_sequence CXINPUT { $$ = APPEND($1, "[lower-case(name())='input']"); }
  451. | possibly_empty_sequence CXENABLED { $$ = APPEND($1, "[lower-case(name())='input' and not(@disabled)]"); }
  452. | possibly_empty_sequence CXDISABLED { $$ = APPEND($1, "[lower-case(name())='input' and @disabled]"); }
  453. | possibly_empty_sequence CXCHECKED { $$ = APPEND($1, "[@checked]"); }
  454. | possibly_empty_sequence CXSELECTED { $$ = APPEND($1, "[@selected]"); }
  455. | possibly_empty_sequence CXFIRSTCH { $$ = PREPEND($1, "*[1]/self::"); }
  456. | possibly_empty_sequence CXLASTCH { $$ = PREPEND($1, "*[last()]/self::"); }
  457. | possibly_empty_sequence CXONLYCH { $$ = PREPEND($1, "*[count()=1]/self::"); }
  458. | possibly_empty_sequence CXTEXT { $$ = INPUT_TYPE($1, text); }
  459. | possibly_empty_sequence CXPASSWORD { $$ = INPUT_TYPE($1, password); }
  460. | possibly_empty_sequence CXRADIO { $$ = INPUT_TYPE($1, radio); }
  461. | possibly_empty_sequence CXCHECKBOX { $$ = INPUT_TYPE($1, checkbox); }
  462. | possibly_empty_sequence CXSUBMIT { $$ = INPUT_TYPE($1, submit); }
  463. | possibly_empty_sequence CXIMAGE { $$ = INPUT_TYPE($1, image); }
  464. | possibly_empty_sequence CXRESET { $$ = INPUT_TYPE($1, reset); }
  465. | possibly_empty_sequence CXBUTTON { $$ = INPUT_TYPE($1, button); }
  466. | possibly_empty_sequence CXFILE { $$ = INPUT_TYPE($1, file); }
  467. ;
  468. possibly_empty_sequence
  469. : simple_selector_sequence
  470. | { $$ = PXP("*"); }
  471. ;
  472. simple_selector_anchor
  473. : type_selector
  474. | universal
  475. ;
  476. type_selector
  477. : namespace_prefix element_name { $$ = pxpath_cat_paths(3, $1, PXP(":"), $2); }
  478. | element_name
  479. ;
  480. namespace_prefix
  481. : SPLAT PIPE { $$ = PXP("*"); }
  482. | Ident PIPE { $$ = $1; }
  483. | PIPE { $$ = PXP("*"); }
  484. ;
  485. element_name
  486. : Ident { $$ = $1; }
  487. ;
  488. universal
  489. : namespace_prefix SPLAT { $$ = pxpath_cat_paths(3, $1, PXP(":"), PXP($2)); }
  490. | SPLAT { $$ = PXP($1); }
  491. ;
  492. NumberLike
  493. : NUMBER { $$ = PXP($1); }
  494. ;
  495. Ident
  496. : NAME { $$ = PXP($1); }
  497. | BSLASHLIT { $$ = PXP($1 + 1); }
  498. | NAME Ident { $$ = pxpath_cat_paths(2, PXP($1), $2); }
  499. | BSLASHLIT Ident { $$ = pxpath_cat_paths(2, PXP($1 + 1), $2); }
  500. | keyword { $$ = PXP($1); }
  501. ;
  502. keyword
  503. : XANCESTOR
  504. | XANCESTORSELF
  505. | XATTR
  506. | XCHILD
  507. | XDESC
  508. | XDESCSELF
  509. | XFOLLOW
  510. | XFOLLOWSIB
  511. | XNS
  512. | XPARENT
  513. | XPRE
  514. | XPRESIB
  515. | XSELF
  516. | XOR
  517. | XAND
  518. | XDIV
  519. | XMOD
  520. | XCOMMENT
  521. | XTEXT
  522. | XPI
  523. | XNODE
  524. ;
  525. StringLike
  526. : Ident
  527. | STRING { $$ = pxpath_new_literal(1, $1); }
  528. ;
  529. OptS
  530. : S { $$ = 0; }
  531. | { $$ = 0; }
  532. ;
  533. %%
  534. char* xpath_alias(char* key) {
  535. char* value = (char*) xmlHashLookup(alias_hash, key);
  536. return value == NULL ? key : value;
  537. }
  538. void init_xpath_alias() {
  539. alias_hash = xmlHashCreate(100);
  540. xmlHashAddEntry(alias_hash, "html", "lib:html-document");
  541. xmlHashAddEntry(alias_hash, "match", "regexp:match");
  542. xmlHashAddEntry(alias_hash, "replace", "regexp:replace");
  543. xmlHashAddEntry(alias_hash, "test", "regexp:test");
  544. xmlHashAddEntry(alias_hash, "with-newlines", "lib:nl");
  545. }
  546. pxpathPtr myparse(char* string){
  547. // start_debugging();
  548. parsed_answer = NULL;
  549. prepare_parse(string);
  550. yyparse();
  551. cleanup_parse();
  552. return parsed_answer;
  553. }
  554. void answer(pxpathPtr a){
  555. parsed_answer = a;
  556. }
  557. void start_debugging(){
  558. yydebug = 1;
  559. return;
  560. }