ref: 4e09200f7e4bf8791c9c720922734e0759206b72
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
;