xref: /onnv-gate/usr/src/cmd/fm/eversholt/common/escparse.y (revision 11202:9f0b4aa8d573)
10Sstevel@tonic-gate %{
20Sstevel@tonic-gate /*
30Sstevel@tonic-gate  * CDDL HEADER START
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
62869Sgavinm  * Common Development and Distribution License (the "License").
72869Sgavinm  * You may not use this file except in compliance with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  *
22*11202SStephen.Hanson@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  *
250Sstevel@tonic-gate  * escparse.y -- parser for esc
260Sstevel@tonic-gate  *
270Sstevel@tonic-gate  * this is the yacc-based parser for Eversholt.  the syntax is simple
280Sstevel@tonic-gate  * and is defined by the LALR(1) grammar described by this file.  there
290Sstevel@tonic-gate  * should be no shift/reduce or reduce/reduce messages when building this
300Sstevel@tonic-gate  * file.
310Sstevel@tonic-gate  *
320Sstevel@tonic-gate  * as the input is parsed, a parse tree is built by calling the
330Sstevel@tonic-gate  * tree_X() functions defined in tree.c.  any syntax errors cause
340Sstevel@tonic-gate  * us to skip to the next semicolon, achieved via the "error" clause
350Sstevel@tonic-gate  * in the stmt rule below.  the yacc state machine code will call
360Sstevel@tonic-gate  * yyerror() in esclex.c and that will keep count of the errors and
370Sstevel@tonic-gate  * display the filename, line number, and current input stream of tokens
380Sstevel@tonic-gate  * to help the user figure out the problem.  the -Y flag to this program
390Sstevel@tonic-gate  * turns on the yacc debugging output which is quite large.  you probably
400Sstevel@tonic-gate  * only need to do that if you're debugging the grammar below.
410Sstevel@tonic-gate  *
420Sstevel@tonic-gate  */
430Sstevel@tonic-gate 
440Sstevel@tonic-gate #include <stdio.h>
450Sstevel@tonic-gate #include <ctype.h>
460Sstevel@tonic-gate #include <string.h>
470Sstevel@tonic-gate #include <stdlib.h>
480Sstevel@tonic-gate #include <unistd.h>
490Sstevel@tonic-gate #include <time.h>
500Sstevel@tonic-gate #include <sys/time.h>
510Sstevel@tonic-gate #include "out.h"
520Sstevel@tonic-gate #include "stable.h"
530Sstevel@tonic-gate #include "literals.h"
540Sstevel@tonic-gate #include "lut.h"
550Sstevel@tonic-gate #include "esclex.h"
560Sstevel@tonic-gate #include "tree.h"
570Sstevel@tonic-gate 
580Sstevel@tonic-gate %}
590Sstevel@tonic-gate %union {
600Sstevel@tonic-gate 	struct tokstr tok;
610Sstevel@tonic-gate 	struct node *np;
620Sstevel@tonic-gate }
630Sstevel@tonic-gate 
640Sstevel@tonic-gate %right '='
650Sstevel@tonic-gate 
660Sstevel@tonic-gate /*
670Sstevel@tonic-gate  * make sure ':' comes immediately after '?' in precedence declarations
680Sstevel@tonic-gate  */
690Sstevel@tonic-gate %right '?'
700Sstevel@tonic-gate %nonassoc ':'
710Sstevel@tonic-gate 
720Sstevel@tonic-gate %left OR
730Sstevel@tonic-gate %left AND
740Sstevel@tonic-gate %left '|'
750Sstevel@tonic-gate %left '^'
760Sstevel@tonic-gate %left '&'
770Sstevel@tonic-gate %left EQ NE
780Sstevel@tonic-gate %left LE GE '<' '>'
790Sstevel@tonic-gate %left LSHIFT RSHIFT
800Sstevel@tonic-gate %left '-' '+'
810Sstevel@tonic-gate %left '*' '%' DIV '/'
820Sstevel@tonic-gate %right '!' '~'
830Sstevel@tonic-gate %left '.'
840Sstevel@tonic-gate 
851414Scindi %token <tok> PROP MASK ARROW EVENT ENGINE ASRU FRU COUNT CONFIG
860Sstevel@tonic-gate %token <tok> ID QUOTE NUMBER IF PATHFUNC
870Sstevel@tonic-gate %type <tok> enameid
880Sstevel@tonic-gate %type <np> root stmtlist stmt nvpairlist nvpair nvname nvexpr
890Sstevel@tonic-gate %type <np> exprlist expr iterid ename pname epname eexprlist ipname iname
906277Scy152378 %type <np> numexpr cexpr func pfunc parglist parg
910Sstevel@tonic-gate %type <np> eventlist event nork norkexpr globid propbody
920Sstevel@tonic-gate 
930Sstevel@tonic-gate %%
940Sstevel@tonic-gate 
950Sstevel@tonic-gate root	: stmtlist
960Sstevel@tonic-gate 		{ (void)tree_root($1); }
970Sstevel@tonic-gate 	;
980Sstevel@tonic-gate 
990Sstevel@tonic-gate stmtlist   : /*empty*/
1000Sstevel@tonic-gate 		{ $$ = NULL; }
1010Sstevel@tonic-gate         | stmtlist stmt
1020Sstevel@tonic-gate 		{ $$ = tree_expr(T_LIST, $1, $2); }
1030Sstevel@tonic-gate 	;
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate stmt	: error ';'
1060Sstevel@tonic-gate      		{ $$ = tree_nothing(); }
1070Sstevel@tonic-gate 	| IF '(' expr ')' stmt
1080Sstevel@tonic-gate 		{ $$ = $5; }
1090Sstevel@tonic-gate 	| IF '(' expr ')' '{' stmtlist '}'
1100Sstevel@tonic-gate 		{ $$ = $6; }
1110Sstevel@tonic-gate 	| EVENT event nvpairlist ';'
1120Sstevel@tonic-gate 		{ $$ = tree_decl(T_EVENT, $2, $3, $1.file, $1.line); }
1130Sstevel@tonic-gate 	| ENGINE event nvpairlist ';'
1140Sstevel@tonic-gate 		{ $$ = tree_decl(T_ENGINE, $2, $3, $1.file, $1.line); }
1150Sstevel@tonic-gate 	| PROP propbody ';'
1160Sstevel@tonic-gate 		{
1170Sstevel@tonic-gate 			$$ = tree_stmt(T_PROP, $2, $1.file, $1.line);
1180Sstevel@tonic-gate 		}
1190Sstevel@tonic-gate 	| MASK propbody ';'
1200Sstevel@tonic-gate 		{
1210Sstevel@tonic-gate 			$$ = tree_stmt(T_MASK, $2, $1.file, $1.line);
1220Sstevel@tonic-gate 		}
1230Sstevel@tonic-gate 	| ASRU pname nvpairlist ';'
1240Sstevel@tonic-gate 		{
1250Sstevel@tonic-gate 			$$ = tree_decl(T_ASRU, $2, $3, $1.file, $1.line);
1260Sstevel@tonic-gate 		}
1270Sstevel@tonic-gate 	| FRU pname nvpairlist ';'
1280Sstevel@tonic-gate 		{
1290Sstevel@tonic-gate 			$$ = tree_decl(T_FRU, $2, $3, $1.file, $1.line);
1300Sstevel@tonic-gate 		}
1310Sstevel@tonic-gate 	| CONFIG ipname nvpairlist ';'
1320Sstevel@tonic-gate 		{
1330Sstevel@tonic-gate 			$$ = tree_decl(T_CONFIG, $2, $3, $1.file, $1.line);
1340Sstevel@tonic-gate 		}
1350Sstevel@tonic-gate 	| /*superfluous semicolons are ignored*/ ';'
1360Sstevel@tonic-gate      		{ $$ = tree_nothing(); }
1370Sstevel@tonic-gate 	;
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate propbody: eventlist nork ARROW nork eventlist
1400Sstevel@tonic-gate 		{
1410Sstevel@tonic-gate 			$$ = tree_arrow($1, $2, $4, $5);
1420Sstevel@tonic-gate 		}
1430Sstevel@tonic-gate 	| propbody nork ARROW nork eventlist
1440Sstevel@tonic-gate 		{
1450Sstevel@tonic-gate 			$$ = tree_arrow($1, $2, $4, $5);
1460Sstevel@tonic-gate 		}
1470Sstevel@tonic-gate 	;
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate nork	: /* empty */
1500Sstevel@tonic-gate 		{ $$ = NULL; }
1510Sstevel@tonic-gate 	| '(' norkexpr ')'
1520Sstevel@tonic-gate 		{ $$ = $2; }
1530Sstevel@tonic-gate 	;
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate norkexpr: NUMBER
1560Sstevel@tonic-gate 		{ $$ = tree_num($1.s, $1.file, $1.line); }
1570Sstevel@tonic-gate 	| ID
1580Sstevel@tonic-gate 		/* really can only be 'A', enforced by check_arrow() later */
1590Sstevel@tonic-gate        		{ $$ = tree_name($1.s, IT_NONE, $1.file, $1.line); }
1600Sstevel@tonic-gate 	| '(' norkexpr ')'
1610Sstevel@tonic-gate 		{ $$ = $2; }
1620Sstevel@tonic-gate 	| norkexpr '-' norkexpr
1630Sstevel@tonic-gate 		{ $$ = tree_expr(T_SUB, $1, $3); }
1640Sstevel@tonic-gate 	| norkexpr '+' norkexpr
1650Sstevel@tonic-gate 		{ $$ = tree_expr(T_ADD, $1, $3); }
1660Sstevel@tonic-gate 	| norkexpr '*' norkexpr
1670Sstevel@tonic-gate 		{ $$ = tree_expr(T_MUL, $1, $3); }
1680Sstevel@tonic-gate 	| norkexpr DIV norkexpr
1690Sstevel@tonic-gate 		{ $$ = tree_expr(T_DIV, $1, $3); }
1700Sstevel@tonic-gate 	| norkexpr '%' norkexpr
1710Sstevel@tonic-gate 		{ $$ = tree_expr(T_MOD, $1, $3); }
1720Sstevel@tonic-gate 	;
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate nvpairlist: /* empty */
1750Sstevel@tonic-gate 		{ $$ = NULL; }
1760Sstevel@tonic-gate 	| nvpair
1770Sstevel@tonic-gate 	| nvpairlist ',' nvpair
1780Sstevel@tonic-gate 		{ $$ = tree_expr(T_LIST, $1, $3); }
1790Sstevel@tonic-gate 	;
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate nvpair	: nvname '=' nvexpr
1820Sstevel@tonic-gate 		{ $$ = tree_expr(T_NVPAIR, $1, $3); }
1830Sstevel@tonic-gate 	| ENGINE '=' nvexpr
1840Sstevel@tonic-gate 		/* "engine" is a reserved word, but a valid property name */
1850Sstevel@tonic-gate 		{
1860Sstevel@tonic-gate 			$$ = tree_expr(T_NVPAIR,
1870Sstevel@tonic-gate 				tree_name($1.s, IT_NONE, $1.file, $1.line), $3);
1880Sstevel@tonic-gate 		}
1891414Scindi 	| COUNT '=' nvexpr
1901414Scindi 		/* "count" is a reserved word, but a valid property name */
1911414Scindi 		{
1921414Scindi 			$$ = tree_expr(T_NVPAIR,
1931414Scindi 				tree_name($1.s, IT_NONE, $1.file, $1.line), $3);
1941414Scindi 		}
1950Sstevel@tonic-gate 	;
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate nvname	: ID
1980Sstevel@tonic-gate 		{ $$ = tree_name($1.s, IT_NONE, $1.file, $1.line); }
1990Sstevel@tonic-gate 	| nvname '-' ID
2000Sstevel@tonic-gate 		{
2010Sstevel@tonic-gate 			/* hack to allow dashes in property names */
2020Sstevel@tonic-gate 			$$ = tree_name_repairdash($1, $3.s);
2030Sstevel@tonic-gate 		}
2040Sstevel@tonic-gate 	;
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate /* the RHS of an nvpair can be a value, or an ename, or an ename@pname */
2070Sstevel@tonic-gate nvexpr	: numexpr
2080Sstevel@tonic-gate 	| ename epname
2090Sstevel@tonic-gate 		{ $$ = tree_event($1, $2, NULL); }
2100Sstevel@tonic-gate 	| pname
2111414Scindi 	| globid
2121414Scindi 	| func
2130Sstevel@tonic-gate 	| NUMBER ID
2140Sstevel@tonic-gate 		/*
2150Sstevel@tonic-gate 		 * ID must be timevals only ("ms", "us", etc.).
2160Sstevel@tonic-gate 		 * enforced by tree_timeval().
2170Sstevel@tonic-gate 		 */
2180Sstevel@tonic-gate 		{ $$ = tree_timeval($1.s, $2.s, $1.file, $1.line); }
2190Sstevel@tonic-gate 	| QUOTE
2200Sstevel@tonic-gate 		{ $$ = tree_quote($1.s, $1.file, $1.line); }
2210Sstevel@tonic-gate 	;
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate /* arithmetic operations, no variables or symbols */
2240Sstevel@tonic-gate numexpr	: numexpr '-' numexpr
2250Sstevel@tonic-gate 		{ $$ = tree_expr(T_SUB, $1, $3); }
2260Sstevel@tonic-gate 	| numexpr '+' numexpr
2270Sstevel@tonic-gate 		{ $$ = tree_expr(T_ADD, $1, $3); }
2280Sstevel@tonic-gate 	| numexpr '*' numexpr
2290Sstevel@tonic-gate 		{ $$ = tree_expr(T_MUL, $1, $3); }
2300Sstevel@tonic-gate 	| numexpr DIV numexpr
2310Sstevel@tonic-gate 		{ $$ = tree_expr(T_DIV, $1, $3); }
2320Sstevel@tonic-gate 	| numexpr '/' numexpr
2330Sstevel@tonic-gate 		{ $$ = tree_expr(T_DIV, $1, $3); }
2340Sstevel@tonic-gate 	| numexpr '%' numexpr
2350Sstevel@tonic-gate 		{ $$ = tree_expr(T_MOD, $1, $3); }
2360Sstevel@tonic-gate  	| '(' numexpr ')'
2370Sstevel@tonic-gate 		{ $$ = $2; }
2380Sstevel@tonic-gate 	| NUMBER
2390Sstevel@tonic-gate 		{ $$ = tree_num($1.s, $1.file, $1.line); }
2400Sstevel@tonic-gate 	;
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate eventlist: event
2430Sstevel@tonic-gate 	| eventlist ',' event
2440Sstevel@tonic-gate 		{ $$ = tree_expr(T_LIST, $1, $3); }
2450Sstevel@tonic-gate 	;
2460Sstevel@tonic-gate 
2470Sstevel@tonic-gate event	: ename epname eexprlist
2480Sstevel@tonic-gate 		{ $$ = tree_event($1, $2, $3); }
2490Sstevel@tonic-gate 	;
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate epname	: /* empty */
2520Sstevel@tonic-gate 		{ $$ = NULL; }
2530Sstevel@tonic-gate 	| '@' pname
2540Sstevel@tonic-gate 		{ $$ = $2; }
2550Sstevel@tonic-gate 	;
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate eexprlist: /* empty */
2580Sstevel@tonic-gate 		{ $$ = NULL; }
2590Sstevel@tonic-gate 	| '{' exprlist '}'
2600Sstevel@tonic-gate 		{ $$ = $2; }
2610Sstevel@tonic-gate 	;
2620Sstevel@tonic-gate 
2630Sstevel@tonic-gate exprlist: expr
2640Sstevel@tonic-gate 	| exprlist ',' expr
2650Sstevel@tonic-gate 		{ $$ = tree_expr(T_LIST, $1, $3); }
2660Sstevel@tonic-gate 	;
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate /*
2690Sstevel@tonic-gate  * note that expr does not include pname, to avoid reduce/reduce
2700Sstevel@tonic-gate  * conflicts between cexpr and iterid involving the use of ID
2710Sstevel@tonic-gate  */
2720Sstevel@tonic-gate expr	: cexpr
2730Sstevel@tonic-gate 	| NUMBER ID
2740Sstevel@tonic-gate 		/*
2750Sstevel@tonic-gate 		 * ID must be timevals only ("ms", "us", etc.).
2760Sstevel@tonic-gate 		 * enforced by tree_timeval().
2770Sstevel@tonic-gate 		 */
2780Sstevel@tonic-gate 		{ $$ = tree_timeval($1.s, $2.s, $1.file, $1.line); }
2790Sstevel@tonic-gate 	;
2800Sstevel@tonic-gate 
2810Sstevel@tonic-gate cexpr	: cexpr '=' cexpr
2820Sstevel@tonic-gate 		{ $$ = tree_expr(T_ASSIGN, $1, $3); }
2830Sstevel@tonic-gate 	| cexpr '?' cexpr
2840Sstevel@tonic-gate 		{ $$ = tree_expr(T_CONDIF, $1, $3); }
2850Sstevel@tonic-gate 	| cexpr ':' cexpr
2860Sstevel@tonic-gate 		{ $$ = tree_expr(T_CONDELSE, $1, $3); }
2870Sstevel@tonic-gate 	| cexpr OR cexpr
2880Sstevel@tonic-gate 		{ $$ = tree_expr(T_OR, $1, $3); }
2890Sstevel@tonic-gate  	| cexpr AND cexpr
2900Sstevel@tonic-gate 		{ $$ = tree_expr(T_AND, $1, $3); }
2910Sstevel@tonic-gate 	| cexpr '|' cexpr
2920Sstevel@tonic-gate 		{ $$ = tree_expr(T_BITOR, $1, $3); }
2930Sstevel@tonic-gate 	| cexpr '^' cexpr
2940Sstevel@tonic-gate 		{ $$ = tree_expr(T_BITXOR, $1, $3); }
2950Sstevel@tonic-gate 	| cexpr '&' cexpr
2960Sstevel@tonic-gate 		{ $$ = tree_expr(T_BITAND, $1, $3); }
2970Sstevel@tonic-gate 	| cexpr EQ cexpr
2980Sstevel@tonic-gate 		{ $$ = tree_expr(T_EQ, $1, $3); }
2990Sstevel@tonic-gate 	| cexpr NE cexpr
3000Sstevel@tonic-gate 		{ $$ = tree_expr(T_NE, $1, $3); }
3010Sstevel@tonic-gate 	| cexpr '<' cexpr
3020Sstevel@tonic-gate 		{ $$ = tree_expr(T_LT, $1, $3); }
3030Sstevel@tonic-gate 	| cexpr LE cexpr
3040Sstevel@tonic-gate 		{ $$ = tree_expr(T_LE, $1, $3); }
3050Sstevel@tonic-gate 	| cexpr '>' cexpr
3060Sstevel@tonic-gate 		{ $$ = tree_expr(T_GT, $1, $3); }
3070Sstevel@tonic-gate 	| cexpr GE cexpr
3080Sstevel@tonic-gate 		{ $$ = tree_expr(T_GE, $1, $3); }
3090Sstevel@tonic-gate 	| cexpr LSHIFT cexpr
3100Sstevel@tonic-gate 		{ $$ = tree_expr(T_LSHIFT, $1, $3); }
3110Sstevel@tonic-gate 	| cexpr RSHIFT cexpr
3120Sstevel@tonic-gate 		{ $$ = tree_expr(T_RSHIFT, $1, $3); }
3130Sstevel@tonic-gate 	| cexpr '-' cexpr
3140Sstevel@tonic-gate 		{ $$ = tree_expr(T_SUB, $1, $3); }
3150Sstevel@tonic-gate 	| cexpr '+' cexpr
3160Sstevel@tonic-gate 		{ $$ = tree_expr(T_ADD, $1, $3); }
3170Sstevel@tonic-gate 	| cexpr '*' cexpr
3180Sstevel@tonic-gate 		{ $$ = tree_expr(T_MUL, $1, $3); }
3190Sstevel@tonic-gate 	| cexpr DIV cexpr
3200Sstevel@tonic-gate 		{ $$ = tree_expr(T_DIV, $1, $3); }
3210Sstevel@tonic-gate 	| cexpr '/' cexpr
3220Sstevel@tonic-gate 		{ $$ = tree_expr(T_DIV, $1, $3); }
3230Sstevel@tonic-gate 	| cexpr '%' cexpr
3240Sstevel@tonic-gate 		{ $$ = tree_expr(T_MOD, $1, $3); }
3250Sstevel@tonic-gate 	|  '!' cexpr
3260Sstevel@tonic-gate 		{ $$ = tree_expr(T_NOT, $2, NULL); }
3270Sstevel@tonic-gate 	|  '~' cexpr
3280Sstevel@tonic-gate 		{ $$ = tree_expr(T_BITNOT, $2, NULL); }
3290Sstevel@tonic-gate 	| '(' cexpr ')'
3300Sstevel@tonic-gate 		{ $$ = $2; }
3310Sstevel@tonic-gate 	| func
3320Sstevel@tonic-gate 	| NUMBER
3330Sstevel@tonic-gate 		{ $$ = tree_num($1.s, $1.file, $1.line); }
3340Sstevel@tonic-gate 	| ID
3350Sstevel@tonic-gate        		{
3360Sstevel@tonic-gate 			/* iteration variable */
3370Sstevel@tonic-gate 			$$ = tree_name($1.s, IT_NONE, $1.file, $1.line);
3380Sstevel@tonic-gate 		}
3390Sstevel@tonic-gate 	| globid
3400Sstevel@tonic-gate 	| QUOTE
3410Sstevel@tonic-gate 		{ $$ = tree_quote($1.s, $1.file, $1.line); }
3420Sstevel@tonic-gate 	;
3430Sstevel@tonic-gate 
3440Sstevel@tonic-gate func	: ID '(' ')'
3450Sstevel@tonic-gate 		{ $$ = tree_func($1.s, NULL, $1.file, $1.line); }
3460Sstevel@tonic-gate 	| ID '(' exprlist ')'
3470Sstevel@tonic-gate 		{ $$ = tree_func($1.s, $3, $1.file, $1.line); }
3480Sstevel@tonic-gate 	| PATHFUNC '(' parglist ')'
3490Sstevel@tonic-gate 		{ $$ = tree_func($1.s, $3, $1.file, $1.line); }
3500Sstevel@tonic-gate 	| pfunc
3510Sstevel@tonic-gate 	;
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate parglist: parg
3540Sstevel@tonic-gate 	| parglist ',' parg
3550Sstevel@tonic-gate 		{ $$ = tree_expr(T_LIST, $1, $3); }
3560Sstevel@tonic-gate 	;
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate parg	: pfunc
3590Sstevel@tonic-gate 	| pname
3600Sstevel@tonic-gate 		{ $$ = tree_pname($1); }
3610Sstevel@tonic-gate 	| QUOTE
3620Sstevel@tonic-gate 		{ $$ = tree_quote($1.s, $1.file, $1.line); }
363*11202SStephen.Hanson@Sun.COM 	| ID '(' exprlist ')'
364*11202SStephen.Hanson@Sun.COM 		{ $$ = tree_func($1.s, $3, $1.file, $1.line); }
3650Sstevel@tonic-gate 	;
3660Sstevel@tonic-gate 
3671414Scindi /*
3681414Scindi  * these functions are in the grammar so we can force the arg to be
3691414Scindi  * a path or an event.  they show up as functions in the parse tree.
3701414Scindi  */
3710Sstevel@tonic-gate pfunc	: ASRU '(' pname ')'
3720Sstevel@tonic-gate 		{ $$ = tree_func($1.s, tree_pname($3), $1.file, $1.line); }
3730Sstevel@tonic-gate 	| FRU '(' pname ')'
3740Sstevel@tonic-gate 		{ $$ = tree_func($1.s, tree_pname($3), $1.file, $1.line); }
3751414Scindi 	| COUNT '(' event ')'
3761414Scindi 		{ $$ = tree_func($1.s, $3, $1.file, $1.line); }
3770Sstevel@tonic-gate 	;
3780Sstevel@tonic-gate 
3790Sstevel@tonic-gate globid	: '$' ID
3800Sstevel@tonic-gate        		{ $$ = tree_globid($2.s, $2.file, $2.line); }
3810Sstevel@tonic-gate 	;
3820Sstevel@tonic-gate 
3830Sstevel@tonic-gate iterid	: ID
3840Sstevel@tonic-gate        		{ $$ = tree_name($1.s, IT_VERTICAL, $1.file, $1.line); }
3850Sstevel@tonic-gate 	| ID '[' ']'
3860Sstevel@tonic-gate        		{ $$ = tree_name($1.s, IT_VERTICAL, $1.file, $1.line); }
3870Sstevel@tonic-gate 	| ID '[' cexpr ']'
3880Sstevel@tonic-gate        		{
3890Sstevel@tonic-gate 			$$ = tree_name_iterator(
3900Sstevel@tonic-gate 			   tree_name($1.s, IT_VERTICAL, $1.file, $1.line), $3);
3910Sstevel@tonic-gate 		}
3920Sstevel@tonic-gate 	| ID '<' '>'
3930Sstevel@tonic-gate        		{ $$ = tree_name($1.s, IT_HORIZONTAL, $1.file, $1.line); }
3940Sstevel@tonic-gate 	| ID '<' ID '>'
3950Sstevel@tonic-gate        		{
3960Sstevel@tonic-gate 			$$ = tree_name_iterator(
3970Sstevel@tonic-gate 			    tree_name($1.s, IT_HORIZONTAL, $1.file, $1.line),
3980Sstevel@tonic-gate 			    tree_name($3.s, IT_NONE, $3.file, $3.line));
3990Sstevel@tonic-gate 		}
4002869Sgavinm 	| ID '-' iterid
4012869Sgavinm 		{
4022869Sgavinm 			/* hack to allow dashes in path name components */
4032869Sgavinm 			$$ = tree_name_repairdash2($1.s, $3);
4042869Sgavinm 		}
4050Sstevel@tonic-gate 	;
4060Sstevel@tonic-gate 
4070Sstevel@tonic-gate /* iname is an ID where we can peel numbers off the end */
4080Sstevel@tonic-gate iname	: ID
4090Sstevel@tonic-gate        		{ $$ = tree_iname($1.s, $1.file, $1.line); }
4100Sstevel@tonic-gate 	;
4110Sstevel@tonic-gate 
4120Sstevel@tonic-gate /* base case of ID.ID instead of just ID requires ename to contain one dot */
4130Sstevel@tonic-gate ename	: ID '.' enameid
4140Sstevel@tonic-gate        		{
4150Sstevel@tonic-gate 			$$ = tree_name_append(
4160Sstevel@tonic-gate 			    tree_name($1.s, IT_ENAME, $1.file, $1.line),
4170Sstevel@tonic-gate 			    tree_name($3.s, IT_NONE, $3.file, $3.line));
4180Sstevel@tonic-gate 		}
4190Sstevel@tonic-gate 	| ename '.' enameid
4200Sstevel@tonic-gate 		{
4210Sstevel@tonic-gate 			$$ = tree_name_append($1,
4220Sstevel@tonic-gate 			    tree_name($3.s, IT_NONE, $3.file, $3.line));
4230Sstevel@tonic-gate 		}
4240Sstevel@tonic-gate 	| ename '-' enameid
4250Sstevel@tonic-gate 		{
4260Sstevel@tonic-gate 			/*
4270Sstevel@tonic-gate 			 * hack to allow dashes in class names.  when we
4280Sstevel@tonic-gate 			 * detect the dash here, we know we're in a class
4290Sstevel@tonic-gate 			 * name because the left recursion of this rule
4300Sstevel@tonic-gate 			 * means we've already matched at least:
4310Sstevel@tonic-gate 			 * 	ID '.' ID
4320Sstevel@tonic-gate 			 * so the ename here has an incomplete final
4330Sstevel@tonic-gate 			 * component (because the lexer stopped at the
4340Sstevel@tonic-gate 			 * dash).  so we repair that final component here.
4350Sstevel@tonic-gate 			 */
4360Sstevel@tonic-gate 			$$ = tree_name_repairdash($1, $3.s);
4370Sstevel@tonic-gate 		}
4380Sstevel@tonic-gate 	;
4390Sstevel@tonic-gate 
4400Sstevel@tonic-gate /* like an ID, but we let reserved words act unreserved in enames */
4410Sstevel@tonic-gate enameid	: ID
4420Sstevel@tonic-gate 	| PROP
4430Sstevel@tonic-gate 	| MASK
4440Sstevel@tonic-gate 	| EVENT
4450Sstevel@tonic-gate 	| ENGINE
4460Sstevel@tonic-gate 	| ASRU
4470Sstevel@tonic-gate 	| FRU
4480Sstevel@tonic-gate 	| CONFIG
4490Sstevel@tonic-gate 	| IF
4500Sstevel@tonic-gate 	;
4510Sstevel@tonic-gate 
4520Sstevel@tonic-gate /* pname is a pathname, like x/y, x<i>/y[0], etc */
4530Sstevel@tonic-gate pname	: iterid
4540Sstevel@tonic-gate 	| pname '/' iterid
4550Sstevel@tonic-gate 		{ $$ = tree_name_append($1, $3); }
4560Sstevel@tonic-gate 	;
4570Sstevel@tonic-gate 
4580Sstevel@tonic-gate /* ipname is an "instanced" pathname, like x0/y1 */
4590Sstevel@tonic-gate ipname	: iname
4600Sstevel@tonic-gate 	| ipname '/' iname
4610Sstevel@tonic-gate 		{ $$ = tree_name_append($1, $3); }
4620Sstevel@tonic-gate 	;
4630Sstevel@tonic-gate 
4640Sstevel@tonic-gate %%
465