ref: 47a288683dbdc55c5df9b9f65db9909de6021af0
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
;