shithub: xml-9atom

ref: ce4a8027322c53b2832f221e2956c90dcd65fd1a
dir: /libxpath/xmlpath.y/

View raw version
%{
#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
	;