ref: f1e559d47916b74f473153a0a04df6956ca4052b
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; Node *nd; } %token <i> CHILD PARENT SELF ANCESTOR ANCESTOR_OR_SELF DESCENDANT %token <i> DESCENDANT_OR_SELF DSLASH %token <i> FOLLOWING FOLLOWING_SIBLING PRECEDING PRECEDING_SIBLING %token <i> ATTRIBUTE NAMESPACE %token <i> AND OR EQ NEQ LT GT LE GE %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 <nd> specl %left EQ NEQ %left LT GT %left LE GE %left AND %left OR %left '/' DSLASH CHILD %left DESCENDANT_OR_SELF %% path: node | /* empty */ { $$ = addnode(nil, Nroot, nil); } | path DSLASH path { $3->type = Ndescself; $$ = chainnode($1, $3); } | path '/' DESCENDANT_OR_SELF path { $4->type = Ndescself; $$ = chainnode($1, $4); } | path '/' path { $$ = chainnode($1, $3); } | path '/' CHILD path { $$ = chainnode($1, $4); } | path AND path { $$ = addcondcnode(Nand, $1, $3); } | path OR path { $$ = addcondcnode(Nor, $1, $3); } | path EQ path { $$ = addcondcnode(Neq, $1, $3); } | path NEQ path { $$ = addcondcnode(Nneq, $1, $3); } | path LT path { $$ = addcondcnode(Nlt, $1, $3); } | path GT path { $$ = addcondcnode(Ngt, $1, $3); } | path LE path { $$ = addcondcnode(Nle, $1, $3); } | path GE path { $$ = addcondcnode(Nge, $1, $3); } ; 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: '[' path ']' { $$ = $2; } | specl '[' path ']' { $$ = addcondcnode(Nand, $1, $3); } ; attr: '@' name { $$ = $2; } | ATTRIBUTE name { $$ = $2; } ; func: name '(' ')' { $$ = addnode($1, Nfunction, nil); } ; number: NUMBER ; name: NAME ;