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