nameSyntaxYacc.y revision 7c478bd95313f5f23a4c958a745db2134aa03244
%{
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* Copyright (c) 2000-2001 by Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/* This is the yacc grammar for the libfru NamingSyntax */
#include <assert.h>
#include <stdio.h>
#include "Parser.h"
//#define YYDEBUG 1
// Parser Globals.
extern fru_errno_t gParserErrno;
extern char *gParserString;
extern Ancestor *gParserAnts;
extern PathDef *gParserHead;
extern int *gParserAbs;
extern void yyerror (const char *msg);
extern int yylex (void);
%}
%union {
int num;
char *name;
PathDef *pathDef;
}
%token SEPIDENT ITERBEGIN ITEREND
%token LAST ADD
%token <num> NUMBER
%token <name> NAME
%type <pathDef> recordpath element
%type <num> itercount
%left SEPIDENT
%%
fullpath : recordpath
{
gParserHead = $1;
gParserAnts
= Ancestor::listTaggedAncestors((char *)$1->def->name);
}
;
recordpath : element
{
$$ = $1;
}
| element SEPIDENT recordpath
{
if ($1->def->dataType != FDTYPE_Record)
{
yyerror (NULL);
YYABORT;
}
int found = 0;
for ( int i=0;i<$1->def->enumCount;i++)
{
if ( strcmp ($3->def->name, $1->def->enumTable[i].text) == 0 )
found = 1;
}
if ( !found )
{
yyerror (NULL);
YYABORT;
}
// insert it in the list.
$1->next = $3;
// return the head of the list.
$$ = $1;
}
| SEPIDENT recordpath
{
// absolute path definitions MUST start with tagged elements.
if ( $2->def->tagType == FRU_X )
{
yyerror ("First Element of absolute path MUST be tagged");
YYABORT;
}
*gParserAbs = 1;
$$ = $2;
}
;
element : NAME
{
const fru_regdef_t *def = fru_reg_lookup_def_by_name($1);
if ( def == NULL )
{
yyerror (NULL);
gParserErrno = FRU_NOREGDEF;
free ($1); // the lexer allocates this memory.
YYABORT;
}
PathDef *pathDef = new PathDef;
pathDef->def = (fru_regdef_t *)def;
pathDef->iterIndex = 0;
pathDef->next = NULL;
free ($1); // the lexer allocates this memory.
$$ = pathDef;
}
| NAME ITERBEGIN itercount ITEREND
{
const fru_regdef_t *def = fru_reg_lookup_def_by_name($1);
if ( def == NULL )
{
yyerror (NULL);
gParserErrno = FRU_NOREGDEF;
free ($1); // the lexer allocates this memory.
YYABORT;
}
if ( def->iterationType == FRU_NOT_ITERATED )
{
yyerror (NULL);
free ($1); // the lexer allocates this memory.
YYABORT;
}
if ( ($3 != PathDef::lastIteration) &&
($3 != PathDef::addIteration) )
{
if ( ($3 >= def->iterationCount) || ($3 < 0) )
{
yyerror (NULL);
free ($1); // the lexer allocates this memory.
YYABORT;
}
}
PathDef *pathDef = new PathDef;
pathDef->def = (fru_regdef_t *)def;
pathDef->iterIndex = $3;
pathDef->next = NULL;
free ($1); // the lexer allocates this memory.
$$ = pathDef;
}
;
itercount : NUMBER
{ $$ = $1; }
| LAST
{ $$ = PathDef::lastIteration; }
| ADD
{ $$ = PathDef::addIteration; }
;
%%
void
yyerror (const char *msg)
{
gParserErrno = FRU_INVALPATH;
}
// just to override what the library should have done.
int yywrap (void) { return 1; }