1 %{
2 /*
3  * CDDL HEADER START
4  *
5  * The contents of this file are subject to the terms of the
6  * Common Development and Distribution License, Version 1.0 only
7  * (the "License").  You may not use this file except in compliance
8  * with the License.
9  *
10  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11  * or http://www.opensolaris.org/os/licensing.
12  * See the License for the specific language governing permissions
13  * and limitations under the License.
14  *
15  * When distributing Covered Code, include this CDDL HEADER in each
16  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17  * If applicable, add the following below this CDDL HEADER, with the
18  * fields enclosed by brackets "[]" replaced with your own identifying
19  * information: Portions Copyright [yyyy] [name of copyright owner]
20  *
21  * CDDL HEADER END
22  *
23  * Copyright (c) 2000-2001 by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /* This is the yacc grammar for the libfru NamingSyntax */
30 #include <assert.h>
31 #include <stdio.h>
32 
33 #include "Parser.h"
34 
35 //#define YYDEBUG 1
36 
37 // Parser Globals.
38 extern fru_errno_t gParserErrno;
39 extern char *gParserString;
40 extern Ancestor *gParserAnts;
41 extern PathDef *gParserHead;
42 extern int *gParserAbs;
43 
44 extern void yyerror (const char *msg);
45 extern int  yylex   (void);
46 
47 %}
48 
49 %union {
50    int      num;
51    char    *name;
52    PathDef *pathDef;
53 }
54 
55 %token SEPIDENT ITERBEGIN ITEREND
56 %token LAST ADD
57 %token <num> NUMBER
58 %token <name> NAME
59 
60 %type <pathDef> recordpath element
61 %type <num> itercount
62 
63 %left SEPIDENT
64 
65 %%
66 fullpath   : recordpath
67            {
68               gParserHead = $1;
69               gParserAnts
70 		= Ancestor::listTaggedAncestors((char *)$1->def->name);
71            }
72            ;
73 
74 recordpath : element
75            {
76                $$ = $1;
77            }
78            | element SEPIDENT recordpath
79            {
80               if ($1->def->dataType != FDTYPE_Record)
81               {
82                  yyerror (NULL);
83                  YYABORT;
84               }
85               int found = 0;
86               for ( int i=0;i<$1->def->enumCount;i++)
87               {
88                  if ( strcmp ($3->def->name, $1->def->enumTable[i].text) == 0 )
89                     found = 1;
90               }
91               if ( !found )
92               {
93                  yyerror (NULL);
94                  YYABORT;
95               }
96               // insert it in the list.
97               $1->next = $3;
98               // return the head of the list.
99               $$ = $1;
100            }
101            | SEPIDENT recordpath
102            {
103               // absolute path definitions MUST start with tagged elements.
104               if ( $2->def->tagType == FRU_X )
105               {
106                  yyerror ("First Element of absolute path MUST be tagged");
107                  YYABORT;
108               }
109               *gParserAbs = 1;
110               $$ = $2;
111            }
112            ;
113 
114 element    : NAME
115            {
116               const fru_regdef_t *def = fru_reg_lookup_def_by_name($1);
117               if ( def == NULL )
118               {
119                  yyerror (NULL);
120                  gParserErrno = FRU_NOREGDEF;
121                  free ($1); // the lexer allocates this memory.
122                  YYABORT;
123               }
124               PathDef *pathDef = new PathDef;
125               pathDef->def = (fru_regdef_t *)def;
126               pathDef->iterIndex = 0;
127               pathDef->next = NULL;
128               free ($1); // the lexer allocates this memory.
129               $$ = pathDef;
130            }
131            | NAME ITERBEGIN itercount ITEREND
132            {
133               const fru_regdef_t *def = fru_reg_lookup_def_by_name($1);
134               if ( def == NULL )
135               {
136                  yyerror (NULL);
137                  gParserErrno = FRU_NOREGDEF;
138                  free ($1); // the lexer allocates this memory.
139                  YYABORT;
140               }
141               if ( def->iterationType == FRU_NOT_ITERATED )
142               {
143                  yyerror (NULL);
144                  free ($1); // the lexer allocates this memory.
145                  YYABORT;
146               }
147               if ( ($3 != PathDef::lastIteration) &&
148 			($3 != PathDef::addIteration) )
149               {
150                  if ( ($3 >= def->iterationCount) || ($3 < 0) )
151                  {
152                     yyerror (NULL);
153                     free ($1); // the lexer allocates this memory.
154                     YYABORT;
155                  }
156               }
157               PathDef *pathDef = new PathDef;
158               pathDef->def = (fru_regdef_t *)def;
159               pathDef->iterIndex = $3;
160               pathDef->next = NULL;
161               free ($1); // the lexer allocates this memory.
162               $$ = pathDef;
163            }
164            ;
165 
166 itercount : NUMBER
167             { $$ = $1; }
168           | LAST
169             { $$ = PathDef::lastIteration; }
170           | ADD
171             { $$ = PathDef::addIteration; }
172           ;
173 
174 %%
175 
176 void
177 yyerror (const char *msg)
178 {
179    gParserErrno = FRU_INVALPATH;
180 }
181 
182 // just to override what the library should have done.
yywrap(void)183 int yywrap (void) { return 1; }
184 
185