%{
#include <assert.h>
#include <stdio.h>
#include "Parser.h"
extern fru_errno_t gParserErrno;
extern char *gParserString;
extern Ancestor *gParserAnts;
extern PathDef *gParserHead;
extern int *gParserAbs;
#ifdef __cplusplus
extern "C" {
#endif
extern int yyerror(const char *msg);
extern int yylex(void);
extern int yywrap (void);
#ifdef __cplusplus
}
#endif
%}
%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)
{
(void) 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 )
{
(void) yyerror (NULL);
YYABORT;
}
$1->next = $3;
$$ = $1;
}
| SEPIDENT recordpath
{
if ( $2->def->tagType == FRU_X )
{
(void) 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 )
{
(void) yyerror (NULL);
gParserErrno = FRU_NOREGDEF;
free ($1);
YYABORT;
}
PathDef *pathDef = new PathDef;
pathDef->def = (fru_regdef_t *)def;
pathDef->iterIndex = 0;
pathDef->next = NULL;
free ($1);
$$ = pathDef;
}
| NAME ITERBEGIN itercount ITEREND
{
const fru_regdef_t *def = fru_reg_lookup_def_by_name($1);
if ( def == NULL )
{
(void) yyerror (NULL);
gParserErrno = FRU_NOREGDEF;
free ($1);
YYABORT;
}
if ( def->iterationType == FRU_NOT_ITERATED )
{
(void) yyerror (NULL);
free ($1);
YYABORT;
}
if ( ($3 != PathDef::lastIteration) &&
($3 != PathDef::addIteration) )
{
if ( ($3 >= def->iterationCount) || ($3 < 0) )
{
(void) yyerror (NULL);
free ($1);
YYABORT;
}
}
PathDef *pathDef = new PathDef;
pathDef->def = (fru_regdef_t *)def;
pathDef->iterIndex = $3;
pathDef->next = NULL;
free ($1);
$$ = pathDef;
}
;
itercount : NUMBER
{ $$ = $1; }
| LAST
{ $$ = PathDef::lastIteration; }
| ADD
{ $$ = PathDef::addIteration; }
;
%%
int
yyerror (const char *msg)
{
gParserErrno = FRU_INVALPATH;
return (0);
}
int yywrap (void)
{
return (1);
}