/*  I am extending yacc's grammar in two aspects: (1), string literals
 *  are legal where character literals are legal, and (2), the first
 *  ("declarations") part is as optional as the trailer.  Both changes
 *  are intended to allow conversion of arbitrary grammars, rather than
 *  just YACC's specific input format.
 */
%token	<list> WS CCODE PREFIX ID CURLS TAG NUMBER RWORD TOKEN
%token	 MARK START UNION PREC
%type	<list> ws spec tail defs def nlist name rules rule body prec elem elems 
%type	<list> r_rules

%union {
	struct list * list;
}

%%
spec:	  ws defs MARK ws rules tail  
spec:	ws rules tail 
	;

ws:	  ws WS			
	| /* empty */		
	;

tail:	  MARK 			
	| ws
	;

defs: 	  defs def		
	| error  WS		
	| ws
	;

def: 	  START ws ID ws	
	| UNION ws CCODE ws	
	| TOKEN ws TAG ws nlist 
	| TOKEN ws nlist	
	| RWORD ws TAG ws nlist 
	| RWORD ws nlist	
	| CURLS ws		
	;

nlist:	  name
	| nlist name 		
	| nlist ',' ws name 	
	;

name:	  ID ws			
	| ID ws NUMBER ws	
	;

rules:	  PREFIX ws body prec r_rules 
	;

r_rules:  /* empty */ 		
	| r_rules rule		
	;

rule:	  PREFIX ws body prec 	
	| '|' ws body prec	
	;

body:	  /* empty */		
	| elems
	;

elems:	  elem			
	| elems elem		
	;

elem:	  ID ws			
	| CCODE ws		
	;

prec:	  /* empty */		
	| PREC ws ID ws		 
	| PREC ws ID ws CCODE ws  
	| prec ';' ws		
	;

%%