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 /* This is the yacc grammar for the libfru NamingSyntax */
28 #include <assert.h>
29 #include <stdio.h>
30 
31 #include "Parser.h"
32 
33 //#define YYDEBUG 1
34 
35 // Parser Globals.
36 extern fru_errno_t gParserErrno;
37 extern char *gParserString;
38 extern Ancestor *gParserAnts;
39 extern PathDef *gParserHead;
40 extern int *gParserAbs;
41 
42 #ifdef	__cplusplus
43 extern "C" {
44 #endif
45 extern void yyerror(const char *msg);
46 extern int yylex(void);
47 extern int yywrap (void);
48 #ifdef	__cplusplus
49 }
50 #endif
51 
52 %}
53 
54 %union {
55    int      num;
56    char    *name;
57    PathDef *pathDef;
58 }
59 
60 %token SEPIDENT ITERBEGIN ITEREND
61 %token LAST ADD
62 %token <num> NUMBER
63 %token <name> NAME
64 
65 %type <pathDef> recordpath element
66 %type <num> itercount
67 
68 %left SEPIDENT
69 
70 %%
71 fullpath   : recordpath
72            {
73               gParserHead = $1;
74               gParserAnts
75 		= Ancestor::listTaggedAncestors((char *)$1->def->name);
76            }
77            ;
78 
79 recordpath : element
80            {
81                $$ = $1;
82            }
83            | element SEPIDENT recordpath
84            {
85               if ($1->def->dataType != FDTYPE_Record)
86               {
87                  yyerror (NULL);
88                  YYABORT;
89               }
90               int found = 0;
91               for ( int i=0;i<$1->def->enumCount;i++)
92               {
93                  if ( strcmp ($3->def->name, $1->def->enumTable[i].text) == 0 )
94                     found = 1;
95               }
96               if ( !found )
97               {
98                  yyerror (NULL);
99                  YYABORT;
100               }
101               // insert it in the list.
102               $1->next = $3;
103               // return the head of the list.
104               $$ = $1;
105            }
106            | SEPIDENT recordpath
107            {
108               // absolute path definitions MUST start with tagged elements.
109               if ( $2->def->tagType == FRU_X )
110               {
111                  yyerror ("First Element of absolute path MUST be tagged");
112                  YYABORT;
113               }
114               *gParserAbs = 1;
115               $$ = $2;
116            }
117            ;
118 
119 element    : NAME
120            {
121               const fru_regdef_t *def = fru_reg_lookup_def_by_name($1);
122               if ( def == NULL )
123               {
124                  yyerror (NULL);
125                  gParserErrno = FRU_NOREGDEF;
126                  free ($1); // the lexer allocates this memory.
127                  YYABORT;
128               }
129               PathDef *pathDef = new PathDef;
130               pathDef->def = (fru_regdef_t *)def;
131               pathDef->iterIndex = 0;
132               pathDef->next = NULL;
133               free ($1); // the lexer allocates this memory.
134               $$ = pathDef;
135            }
136            | NAME ITERBEGIN itercount ITEREND
137            {
138               const fru_regdef_t *def = fru_reg_lookup_def_by_name($1);
139               if ( def == NULL )
140               {
141                  yyerror (NULL);
142                  gParserErrno = FRU_NOREGDEF;
143                  free ($1); // the lexer allocates this memory.
144                  YYABORT;
145               }
146               if ( def->iterationType == FRU_NOT_ITERATED )
147               {
148                  yyerror (NULL);
149                  free ($1); // the lexer allocates this memory.
150                  YYABORT;
151               }
152               if ( ($3 != PathDef::lastIteration) &&
153 			($3 != PathDef::addIteration) )
154               {
155                  if ( ($3 >= def->iterationCount) || ($3 < 0) )
156                  {
157                     yyerror (NULL);
158                     free ($1); // the lexer allocates this memory.
159                     YYABORT;
160                  }
161               }
162               PathDef *pathDef = new PathDef;
163               pathDef->def = (fru_regdef_t *)def;
164               pathDef->iterIndex = $3;
165               pathDef->next = NULL;
166               free ($1); // the lexer allocates this memory.
167               $$ = pathDef;
168            }
169            ;
170 
171 itercount : NUMBER
172             { $$ = $1; }
173           | LAST
174             { $$ = PathDef::lastIteration; }
175           | ADD
176             { $$ = PathDef::addIteration; }
177           ;
178 
179 %%
180 
181 void
182 yyerror (const char *msg)
183 {
184    gParserErrno = FRU_INVALPATH;
185 }
186 
187 // just to override what the library should have done.
yywrap(void)188 int yywrap (void) { return 1; }
189 
190