ref: ce4a8027322c53b2832f221e2956c90dcd65fd1a
dir: /libxpath/xmlpath.y/
%{ #include <u.h> #include <libc.h> #include <xml.h> #include <xpath.h> #include "dat.h" extern int yylex(void); extern int yyparse(void); int yyxstep; void yyerror(char *s) { werrstr("%s", s); } %} %union { int i; int n; Name *nm; Cond *c; Node *nd; } %token <i> CHILD PARENT SELF ANCESTOR ANCESTOR_OR_SELF DESCENDANT %token <i> DESCENDANT_OR_SELF %token <i> FOLLOWING FOLLOWING_SIBLING PRECEDING PRECEDING_SIBLING %token <i> ATTRIBUTE NAMESPACE %token <i> AND OR %token <nm> NAME %token <nm> QUOTE %token <n> NUMBER %type <nm> name %type <n> number %type <nm> attr %type <nd> node %type <nd> func %type <nd> path %type <c> specl %type <c> slist %left AND %left OR %left '=' %% path: node | /* empty */ { $$ = addnode(nil, Nroot, nil); } | path '/' '/' node { $4->type = Ndescself; $$ = chainnode($1, $4); } | path '/' DESCENDANT_OR_SELF node { $4->type = Ndescself; $$ = chainnode($1, $4); } | path '/' node { $$ = chainnode($1, $3); } | path '/' CHILD node { $$ = chainnode($1, $4); } ; node: name { $$ = addnode($1, Nchild, nil); } | name specl { $$ = addnode($1, Nchild, $2); } | number { $$ = addnoden($1, nil); } | number specl { $$ = addnoden($1, $2); } | attr { $$ = addnode($1, Nattribute, nil); } | func ; specl: '[' slist ']' { $$ = $2; } | specl '[' slist ']' { $$ = addcondb(CTand, $1, $3); } ; slist: number { $$ = addcondi($1); } | attr { $$ = addcondhasattr($1); } | slist AND slist { $$ = addcondb(CTand, $1, $3); } | slist OR slist { $$ = addcondb(CTor, $1, $3); } | path '=' path { $$ = addcondcnode(CTeq, $1, $3); } ; attr: '@' name { $$ = $2; } | ATTRIBUTE name { $$ = $2; } ; func: name '(' ')' { $$ = addnode($1, Nfunction, nil); } ; number: NUMBER ; name: NAME ;