5 * The contents of this file are subject to the terms of the
6 * Common Development and Distribution License (the "License").
7 * You may not use this file except in compliance with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
25 * escparse.y -- parser for esc
27 * this is the yacc-based parser for Eversholt. the syntax is simple
28 * and is defined by the LALR(1) grammar described by this file. there
29 * should be no shift/reduce or reduce/reduce messages when building this
32 * as the input is parsed, a parse tree is built by calling the
33 * tree_X() functions defined in tree.c. any syntax errors cause
34 * us to skip to the next semicolon, achieved via the "error" clause
35 * in the stmt rule below. the yacc state machine code will call
36 * yyerror() in esclex.c and that will keep count of the errors and
37 * display the filename, line number, and current input stream of tokens
38 * to help the user figure out the problem. the -Y flag to this program
39 * turns on the yacc debugging output which is quite large. you probably
40 * only need to do that if you're debugging the grammar below.
67 * make sure ':' comes immediately after '?' in precedence declarations
85 %token
<tok
> PROP MASK ARROW EVENT ENGINE ASRU FRU COUNT CONFIG
86 %token
<tok
> ID QUOTE NUMBER IF PATHFUNC
88 %type
<np
> root stmtlist stmt nvpairlist nvpair nvname nvexpr
89 %type
<np
> exprlist expr iterid ename pname epname eexprlist ipname iname
90 %type
<np
> numexpr cexpr func pfunc parglist parg
91 %type
<np
> eventlist event nork norkexpr globid propbody
96 { (void)tree_root
($1); }
102 { $$
= tree_expr
(T_LIST
, $1, $2); }
106 { $$
= tree_nothing
(); }
107 | IF
'(' expr
')' stmt
109 | IF
'(' expr
')' '{' stmtlist
'}'
111 | EVENT event nvpairlist
';'
112 { $$
= tree_decl
(T_EVENT
, $2, $3, $1.file
, $1.line
); }
113 | ENGINE event nvpairlist
';'
114 { $$
= tree_decl
(T_ENGINE
, $2, $3, $1.file
, $1.line
); }
117 $$
= tree_stmt
(T_PROP
, $2, $1.file
, $1.line
);
121 $$
= tree_stmt
(T_MASK
, $2, $1.file
, $1.line
);
123 | ASRU pname nvpairlist
';'
125 $$
= tree_decl
(T_ASRU
, $2, $3, $1.file
, $1.line
);
127 | FRU pname nvpairlist
';'
129 $$
= tree_decl
(T_FRU
, $2, $3, $1.file
, $1.line
);
131 | CONFIG ipname nvpairlist
';'
133 $$
= tree_decl
(T_CONFIG
, $2, $3, $1.file
, $1.line
);
135 |
/*superfluous semicolons are ignored*/ ';'
136 { $$
= tree_nothing
(); }
139 propbody: eventlist nork ARROW nork eventlist
141 $$
= tree_arrow
($1, $2, $4, $5);
143 | propbody nork ARROW nork eventlist
145 $$
= tree_arrow
($1, $2, $4, $5);
156 { $$
= tree_num
($1.s
, $1.file
, $1.line
); }
158 /* really can only be 'A', enforced by check_arrow() later */
159 { $$
= tree_name
($1.s
, IT_NONE
, $1.file
, $1.line
); }
162 | norkexpr
'-' norkexpr
163 { $$
= tree_expr
(T_SUB
, $1, $3); }
164 | norkexpr
'+' norkexpr
165 { $$
= tree_expr
(T_ADD
, $1, $3); }
166 | norkexpr
'*' norkexpr
167 { $$
= tree_expr
(T_MUL
, $1, $3); }
168 | norkexpr DIV norkexpr
169 { $$
= tree_expr
(T_DIV
, $1, $3); }
170 | norkexpr
'%' norkexpr
171 { $$
= tree_expr
(T_MOD
, $1, $3); }
174 nvpairlist: /* empty */
177 | nvpairlist
',' nvpair
178 { $$
= tree_expr
(T_LIST
, $1, $3); }
181 nvpair
: nvname
'=' nvexpr
182 { $$
= tree_expr
(T_NVPAIR
, $1, $3); }
184 /* "engine" is a reserved word, but a valid property name */
186 $$
= tree_expr
(T_NVPAIR
,
187 tree_name
($1.s
, IT_NONE
, $1.file
, $1.line
), $3);
190 /* "count" is a reserved word, but a valid property name */
192 $$
= tree_expr
(T_NVPAIR
,
193 tree_name
($1.s
, IT_NONE
, $1.file
, $1.line
), $3);
198 { $$
= tree_name
($1.s
, IT_NONE
, $1.file
, $1.line
); }
201 /* hack to allow dashes in property names */
202 $$
= tree_name_repairdash
($1, $3.s
);
206 /* the RHS of an nvpair can be a value, or an ename, or an ename@pname */
209 { $$
= tree_event
($1, $2, NULL
); }
215 * ID must be timevals only ("ms", "us", etc.).
216 * enforced by tree_timeval().
218 { $$
= tree_timeval
($1.s
, $2.s
, $1.file
, $1.line
); }
220 { $$
= tree_quote
($1.s
, $1.file
, $1.line
); }
223 /* arithmetic operations, no variables or symbols */
224 numexpr
: numexpr
'-' numexpr
225 { $$
= tree_expr
(T_SUB
, $1, $3); }
226 | numexpr
'+' numexpr
227 { $$
= tree_expr
(T_ADD
, $1, $3); }
228 | numexpr
'*' numexpr
229 { $$
= tree_expr
(T_MUL
, $1, $3); }
230 | numexpr DIV numexpr
231 { $$
= tree_expr
(T_DIV
, $1, $3); }
232 | numexpr
'/' numexpr
233 { $$
= tree_expr
(T_DIV
, $1, $3); }
234 | numexpr
'%' numexpr
235 { $$
= tree_expr
(T_MOD
, $1, $3); }
239 { $$
= tree_num
($1.s
, $1.file
, $1.line
); }
243 | eventlist
',' event
244 { $$
= tree_expr
(T_LIST
, $1, $3); }
247 event
: ename epname eexprlist
248 { $$
= tree_event
($1, $2, $3); }
257 eexprlist: /* empty */
265 { $$
= tree_expr
(T_LIST
, $1, $3); }
269 * note that expr does not include pname, to avoid reduce/reduce
270 * conflicts between cexpr and iterid involving the use of ID
275 * ID must be timevals only ("ms", "us", etc.).
276 * enforced by tree_timeval().
278 { $$
= tree_timeval
($1.s
, $2.s
, $1.file
, $1.line
); }
281 cexpr
: cexpr
'=' cexpr
282 { $$
= tree_expr
(T_ASSIGN
, $1, $3); }
284 { $$
= tree_expr
(T_CONDIF
, $1, $3); }
286 { $$
= tree_expr
(T_CONDELSE
, $1, $3); }
288 { $$
= tree_expr
(T_OR
, $1, $3); }
290 { $$
= tree_expr
(T_AND
, $1, $3); }
292 { $$
= tree_expr
(T_BITOR
, $1, $3); }
294 { $$
= tree_expr
(T_BITXOR
, $1, $3); }
296 { $$
= tree_expr
(T_BITAND
, $1, $3); }
298 { $$
= tree_expr
(T_EQ
, $1, $3); }
300 { $$
= tree_expr
(T_NE
, $1, $3); }
302 { $$
= tree_expr
(T_LT
, $1, $3); }
304 { $$
= tree_expr
(T_LE
, $1, $3); }
306 { $$
= tree_expr
(T_GT
, $1, $3); }
308 { $$
= tree_expr
(T_GE
, $1, $3); }
310 { $$
= tree_expr
(T_LSHIFT
, $1, $3); }
312 { $$
= tree_expr
(T_RSHIFT
, $1, $3); }
314 { $$
= tree_expr
(T_SUB
, $1, $3); }
316 { $$
= tree_expr
(T_ADD
, $1, $3); }
318 { $$
= tree_expr
(T_MUL
, $1, $3); }
320 { $$
= tree_expr
(T_DIV
, $1, $3); }
322 { $$
= tree_expr
(T_DIV
, $1, $3); }
324 { $$
= tree_expr
(T_MOD
, $1, $3); }
326 { $$
= tree_expr
(T_NOT
, $2, NULL
); }
328 { $$
= tree_expr
(T_BITNOT
, $2, NULL
); }
333 { $$
= tree_num
($1.s
, $1.file
, $1.line
); }
336 /* iteration variable */
337 $$
= tree_name
($1.s
, IT_NONE
, $1.file
, $1.line
);
341 { $$
= tree_quote
($1.s
, $1.file
, $1.line
); }
345 { $$
= tree_func
($1.s
, NULL
, $1.file
, $1.line
); }
346 | ID
'(' exprlist
')'
347 { $$
= tree_func
($1.s
, $3, $1.file
, $1.line
); }
348 | PATHFUNC
'(' parglist
')'
349 { $$
= tree_func
($1.s
, $3, $1.file
, $1.line
); }
355 { $$
= tree_expr
(T_LIST
, $1, $3); }
360 { $$
= tree_pname
($1); }
362 { $$
= tree_quote
($1.s
, $1.file
, $1.line
); }
363 | ID
'(' exprlist
')'
364 { $$
= tree_func
($1.s
, $3, $1.file
, $1.line
); }
368 * these functions are in the grammar so we can force the arg to be
369 * a path or an event. they show up as functions in the parse tree.
371 pfunc
: ASRU
'(' pname
')'
372 { $$
= tree_func
($1.s
, tree_pname
($3), $1.file
, $1.line
); }
374 { $$
= tree_func
($1.s
, tree_pname
($3), $1.file
, $1.line
); }
375 | COUNT
'(' event
')'
376 { $$
= tree_func
($1.s
, $3, $1.file
, $1.line
); }
380 { $$
= tree_globid
($2.s
, $2.file
, $2.line
); }
384 { $$
= tree_name
($1.s
, IT_VERTICAL
, $1.file
, $1.line
); }
386 { $$
= tree_name
($1.s
, IT_VERTICAL
, $1.file
, $1.line
); }
389 $$
= tree_name_iterator
(
390 tree_name
($1.s
, IT_VERTICAL
, $1.file
, $1.line
), $3);
393 { $$
= tree_name
($1.s
, IT_HORIZONTAL
, $1.file
, $1.line
); }
396 $$
= tree_name_iterator
(
397 tree_name
($1.s
, IT_HORIZONTAL
, $1.file
, $1.line
),
398 tree_name
($3.s
, IT_NONE
, $3.file
, $3.line
));
402 /* hack to allow dashes in path name components */
403 $$
= tree_name_repairdash2
($1.s
, $3);
407 /* iname is an ID where we can peel numbers off the end */
409 { $$
= tree_iname
($1.s
, $1.file
, $1.line
); }
412 /* base case of ID.ID instead of just ID requires ename to contain one dot */
413 ename
: ID
'.' enameid
415 $$
= tree_name_append
(
416 tree_name
($1.s
, IT_ENAME
, $1.file
, $1.line
),
417 tree_name
($3.s
, IT_NONE
, $3.file
, $3.line
));
421 $$
= tree_name_append
($1,
422 tree_name
($3.s
, IT_NONE
, $3.file
, $3.line
));
427 * hack to allow dashes in class names. when we
428 * detect the dash here, we know we're in a class
429 * name because the left recursion of this rule
430 * means we've already matched at least:
432 * so the ename here has an incomplete final
433 * component (because the lexer stopped at the
434 * dash). so we repair that final component here.
436 $$
= tree_name_repairdash
($1, $3.s
);
440 /* like an ID, but we let reserved words act unreserved in enames */
452 /* pname is a pathname, like x/y, x<i>/y[0], etc */
455 { $$
= tree_name_append
($1, $3); }
458 /* ipname is an "instanced" pathname, like x0/y1 */
461 { $$
= tree_name_append
($1, $3); }