help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Parsing Problem


From: Ali KATKAR
Subject: Parsing Problem
Date: Mon, 12 Aug 2002 12:12:36 +0300

Hi,

I have a problem about structure parsing. I want to know structure name but sdftext doesn't include name. (I use sdf prefix instead of yy)

I want to parse following structure.
struct test_s
 {
  unsigned char uch;
  short int sh;
  long int lo,
               lo2;
 short int ch[2];
 };

And print screen is

Loading Structure File = i1.hp
                <sdftext inside FLEX is i1 >
                <sdftext inside FLEX is h >
                <sdftext inside FLEX is test_s >
                <sdftext inside FLEX is uch >
name_array's text is ;
        value =0 - count=1
var_chain's is ;]
 var_chain_decl's text is short
 var_decl_list's text is short
                <sdftext inside FLEX is sh >
name_array's text is ;
        value =1 - count=1
var_chain's is ;]
 var_chain_decl's text is long
                <sdftext inside FLEX is lo >
name_array's text is ,
        value =2 - count=1
var_chain's is ,]
                <sdftext inside FLEX is lo2 >
name_array's text is ;
 var_chain_decl's text is short
                <sdftext inside FLEX is ch >
        value =1 - count=2
var_chain's is ]]
 var_chain_decl's text is }
 struct_decl's text is struct
-----------------------
Structure = struct  (i want to write  test_s)
type id=1 - count =2
type id=1 - count =1
type id=0 - count =1
-----------------------

I attached my flex and bison files. Is there anybody to help me?
Thanks for your helps.
Ali
 

/* C Structure Lexical Analyzer. */

%{

#include <stdio.h>

#include "stg.h"
#include "sdf_parser.h"

extern int sdfline;

%}
%%

","                     { return COMMA;         }
"#"                     { return LINENO;        }
"{"                     { return OPENPAR;       }
"}"                     { return CLOSEPAR;      }
"("                     { return LPAR;          }
")"                     { return RPAR;          }
"["                     { return LSQPAR;        }
"]"                     { return RSQPAR;        }
";"                     { return SEMICOLON;     }
":"                     { return DOTS;          }
"*"                     { return STAR;          }
"="                     { return EQ;            }
"struct"                { return STRUCT;        }
"unsigned"              { return UNSIGNED;      }
"short"                 { return SHORT;         }
"char"                  { return CHAR;          }
"int"                   { return INT;           }
"long"                  { return LONG;          }
"extern"                { return EXTERN;        }
"void"                  { return VOID;          }
"enum"                  { return ENUM;          }
[0-9]+                  { /*sdflval.val = atoi(sdftext);*/ return NUMBER; }
[A-Za-z_][A-Za-z0-9_]*  { printf("\t\t<sdftext inside FLEX is %s 
>\n",sdftext);return NAME;}
"."                     { return DOT;           }
\                       { ; }
\n                      { sdfline++;            } 
\t                      { ; }
.                       { sdferror("token error"); }

%% /* C Source Starts From Here */

#ifndef sdfwrap
sdfwrap() { return 1; }
#endif

void  mkname( char *name )

/* Look up a name in the symbol table. If not there, create a new entry, 
returning
   the result in "yylval". Note that "yylval" is a union, defined in the yacc 
input,
   and so we must specify which member of the union (in this case "symb") we
   wish to use. We insert the name in the symbol table, but at this stage with
   type T_UNDEF, since we do not know what its type is. */

{
#if 0
        struct symb *t ;                 /* Pointer to symbol looked for */
        char        *s ;                 /* Permanent text of string */
        int          len ;               /* Length of text */


        /* If the string exists return with it in yylval */

        if((t = lookup( name )) != NULL )
        {
                sdflval.symb = t ;
                return ;
        }

        /* Not in symtab. So save the variable name, set up a new symbol table
           node, insert it into the symbol table and assign it to yylval. */

        len = strlen( name ) ;
        s   = (char *)safe_malloc( len + 1 ) ; /* Space for storing lexeme */

        strncpy( s, name, len ) ;
        s[len] = '\0';/*EOS ;*/

        t        = get_symb() ;
        t->type  = T_UNDEF ;             /* Don't know which node type yet */
        t->TEXT1 = s ;                   /* Text argument */

        insert( t ) ;
        sdflval.symb = t ;                /* Symbol type in union */

#endif
}


void  mkval( void )

/* Set up a node for an integer read by the scanner. We use the library routine
   "atoi()" to convert the text of "yytext" to an integer. */

{
#if 0
        yylval.symb = mkconst( atoi( yytext )) ;
#endif

}


void  mktext( void )

/* Text is treated similarly. "mktext()" uses "mkname()" to do most of the 
   work, and then changes the relevant fields. A label is created to mark
   its beginning. Strings will be output as constant data at the end of the 
   program.
   Note that a piece of text cannot be mistaken for a variable name during 
   symbol lookup, since the text field of a text node includes the surrounding 
   quotes. */

{
#if 0
        mkname( yytext ) ;
        yylval.symb->type = T_TEXT ;
        yylval.symb->VAL2 = next_label++ ;
#endif
}

/* C Structure Parser.

   TODO
        add union
        structure inside structure 
        display structure name 
        hold the proccessed structures on hash table
        prepare task table format and processor
        sort structures based on task table
*/

%{
#include <stdio.h>
#include "stg.h"

/* #define YYDEBUG  1 */

#ifdef YYDEBUG 
extern int sdfdebug;
#endif

extern int   sdfline;                   /* Current Source File Line Number */
extern char  *sdftext;
extern int   sdfleng;

unsigned int    curr_enum_val;
stl_t           *curr_stl;
sym_t           *curr_symb;

unsigned int enum_val(enl_t *enl);
void enum_add(enl_t *enl, unsigned int value );
void show_stl(stl_t     *root);

enum
{
    V_BYTE,
    V_SHORT,
    V_LONG,
    V_POINTER,
    V_BIT_BYTE,
    V_BIT_SHORT,
    V_BIT_LONG
};

%}  

/* %union defines the type of attribute to be synthesised by the
   semantic actions. Recall YACC requires a single type, so we must
   use a union to get the kinds we actually need. */

%union
{
    enl_t         *enl;                 /* String for Enums */
    stl_t         *stl;                 /* Struct Lists     */
    sym_t         symb;
    char          *str; 
    unsigned int  val;                  /* Integer Value    */
};

/* Tokens. Most of these don't need types, since they have no
   associated attribute. However variables, integers and text do,
   since they return symbol table nodes as attributes. */

/* Token Declarations */

%start list                             /* Top Most Sentence. */

%token COMMA
%token OPENPAR
%token CLOSEPAR
%token LPAR
%token RPAR
%token LSQPAR
%token RSQPAR
%token SEMICOLON
%token STRUCT
%token UNSIGNED
%token SHORT
%token CHAR
%token INT
%token LONG
%token <val>    NUMBER
%token <str>    NAME
%token LINENO
%token DOT
%token EXTERN
%token DOTS
%token STAR
%token VOID
%token ENUM
%token EQ


/* Here are type declarations for non-terminals. Most non-terminals return
   TAC code as a result, however expressions also return a pointer to the
   symbol holding the result of the calculation. */

%type <stl>     list
%type <stl>     entry
%type <stl>     struct_decl
%type <stl>     var_chain
%type <stl>     var_chain_decl
%type <stl>     var_decl_list

%type <enl>     enum_name

%type <val>     base_type
%type <val>     pointer_type
%type <val>     number
%type <symb>    name_array
%type <char *>  name



%%  

/* Parse Rules */
semicolon               : SEMICOLON
                        | semicolon SEMICOLON
                           {
                                printf("SEMICOLON\n");
                           }
                        ;

/* Preprocessor Source File Line Number */
file_line_no            : LINENO NUMBER NAME DOT NAME
                           {
                                sdfline = $2;
                           }
                        ;

/* Variable Type Declaration */
byte_type               : CHAR
                        | UNSIGNED CHAR 
                        ;

short_type              : SHORT
                        | SHORT INT 
                        | UNSIGNED SHORT 
                        | UNSIGNED SHORT INT
                        ;

long_type               : LONG
                        | INT
                        | LONG INT
                        | UNSIGNED 
                        | UNSIGNED LONG
                        | UNSIGNED LONG INT
                        ;

base_type               : byte_type
                           {
                                $$ = V_BYTE;
                           }
                        | short_type
                           {
                                $$ = V_SHORT;
                           }
                        | long_type
                           {
                                $$ = V_LONG;
                           }
                        ;                

pointer_type            : base_type STAR
                           {
                                $$ = V_POINTER;
                           }
                        | VOID STAR
                           {
                                $$ = V_POINTER;
                           }
                        ;


/* Number Declaration */
number                  : NUMBER
                           {
                                $$ = atoi(sdftext);
                           }
                        /*| enum_name   /* For Enums 
                           {
                                $$ = enum_val($1);
                           }
                        */
                        ;

name                    : NAME
                           {
                           } 

                        ;


/* Structure Declaration */
name_array              : NAME 
                           {
                                
                                sym_t symb;
                                int   len;

                                printf("name_array's text is %s\n",sdftext);
                                len = strlen(sdftext);
                                symb.name = (char *)malloc(len+1);
                                strncpy( symb.name, sdftext, len );
                                symb.name[len]='\0';
                                symb.count = 1;
                                $$ = symb;
                           }
                        | NAME  LSQPAR  number  RSQPAR
                           {
                                sym_t symb;
                                symb.name = &$1;
                                symb.count =$3;
                                $$ = symb;
                                /*$$ = $3;*/
                           }
                        /*| NAME  LSQPAR  number  RSQPAR  LSQPAR  number  RSQPAR
                           {
                                $$ = $3 * $6;
                           }*/
                        ;

var_chain               : base_type name_array 
                           {  
                                                        
                                if ((curr_stl != NULL) && ($1 == curr_stl -> 
value))
                                 {
                                        curr_stl -> value = $1;
                                        curr_stl -> count += $2.count;
                                        $$ = NULL;
                                 }
                                else 
                                 {
                                        stl_t   *s = malloc(sizeof(stl_t));
                                        s -> name[0] = NULL;
                                        s -> value =  $1;
                                        s -> count = $2.count;
                                        s -> next_symb = NULL;
                                        s -> next_node = NULL; 
                                        curr_stl = s;
                                        printf ("\tvalue =%d - 
count=%d\n",$1,$2.count);
                                        $$ = s;                          
                                 }
                                
                                printf ("var_chain's is %s]\n",sdftext);
                                
                           }
                        | pointer_type name_array
                           {
                                $$ = NULL;
                           }
                        | base_type NAME DOTS number
                           {
                                $$ = NULL;
                           }
                        | var_chain COMMA name_array
                           {
                                if ( curr_stl != NULL )
                                 {
                                        curr_stl -> count += $3.count;
                                        $$ = NULL;
                                 }
                                else
                                 {
                                 printf("ERROR\n");
                                 $$ = NULL;
                                 }
                           }
                        | var_chain COMMA STAR name_array
                           {
                                $$ = NULL;
                           }
                        | var_chain COMMA NAME DOTS number
                           {
                                $$ = NULL;
                           }
                        ;

var_chain_decl          : var_chain semicolon
                           {
                                printf(" var_chain_decl's text is 
%s\n",sdftext);                          
                                $$ = $1;
                           }
                        ;

var_decl_list           : var_chain_decl
                           {
                                printf(" var_decl_list's text is 
%s\n",sdftext);                           
                                $$ = $1;
                           }
                        | var_decl_list var_chain_decl
                           {
                                if ($2!= NULL)
                                 {
                                        $2 ->next_symb = $1;
                                        $$ = $2;
                                 }
                                else
                                 {
                                        $$ = $1;
                                 }
                           }
                        ;

struct_decl             : STRUCT NAME OPENPAR var_decl_list CLOSEPAR semicolon
                           {                    
                                stl_t   *s;
                                
                                curr_stl  = NULL;
                                curr_symb = NULL;
                                if($4)
                                 {
                                        s = malloc(sizeof(stl_t));
                                        strncpy(s -> name,sdftext,sdfleng);
                                        s -> value = 0;
                                        s -> count = 0;
                                        s -> next_symb = $4;
                                        s -> next_node = NULL;
                                
                                        printf(" struct_decl's text is 
%s\n",sdftext);                     
                                        /*
                                        printf(" yytext is %s\n",s->name);      
                   

                                        printf("this is a struct\n");
                                        */
                                        printf("-----------------------\n");
                                        show_stl(s);
                                        printf("-----------------------\n");

                                        $$ = s;
                                }
                                else 
                                 $$ = NULL;
                           }
                        ;

/* External Variable Declaration */
var_decl                : var_chain_decl
                           {
                                /* Free */
                           }
                        | EXTERN var_chain_decl
                           {
                                /* Free */
                           }
                        ;

/* External Function Declarations */
func_params             :       
                        | VOID
                        | base_type NAME
                           {
                                /* Free */
                           }
                        | pointer_type NAME
                           {
                                /* Free */
                           }
                        | func_params COMMA base_type NAME
                        | func_params COMMA pointer_type NAME
                           {
                                /* Free */
                           }
                        ;

func_decl               : EXTERN NAME LPAR func_params RPAR semicolon
                        | EXTERN VOID NAME LPAR func_params RPAR semicolon
                        | EXTERN base_type NAME LPAR func_params RPAR semicolon
                        | EXTERN pointer_type NAME LPAR func_params RPAR 
semicolon
                        | VOID NAME LPAR func_params RPAR semicolon
                        | base_type NAME LPAR func_params RPAR semicolon
                           {
                                /* Free */
                           }
                        | pointer_type NAME LPAR func_params RPAR semicolon
                           {
                                /* Free */
                           }
                        ;

/* Enum Declarations */
enum_name               : NAME
                           {
                                $$ = NULL;
                           }
                        ;

enum_entry              : enum_name
                           {
                                enum_add($1, curr_enum_val);
                                curr_enum_val++;
                           }
                        | enum_name  EQ  NUMBER
                           {
                                curr_enum_val = $3;
                                enum_add($1, curr_enum_val);
                                curr_enum_val++;
                           }
                        ;

enum_list               : enum_entry 
                        | enum_list  COMMA  enum_entry
                        ;

enum_decl               : ENUM OPENPAR enum_list CLOSEPAR semicolon
                           {
                                curr_enum_val = 0;
                           }
                        ;

/* File Entry Rules */
entry                   : file_line_no
                           {
                                $$ = NULL;
                           }
                        | struct_decl
                           {
                                $$ = $1;
                           }
                        | var_decl
                           {
                                $$ = NULL;
                           }
                        | func_decl
                           {
                                $$ = NULL;
                           }
                        | enum_decl
                           {
                                $$ = NULL;
                           }
                        ;

list                    : entry
                           {
                                $$ = $1;
                           }
                        | list entry
                           {    
                                if($2 != NULL )
                                 {              
                                        $2 -> next_node = $1;
                                        $$ = $2;
                                 }
                                else
                                 {
                                        $$ = $1;
                                 }

                           }
                        ;
%%

/* C Source Starts From Here */

int sdfline;                    /* Source File Line Number. Used during error 
report. */

/* Lexical Analyzer Or Parser Error Report Function */
sdferror (  char *s  )
{
    fprintf( stderr, "\n\n%s at line:%d\n", s, sdfline );
}

/* Load Source Structures. */
stl_t * load_struct (  char *name  )
{
    FILE        *fp;
    stl_t       *retValue;

    sdfline = 1;
#ifdef YYDEBUG
    sdfdebug = 1;
#endif
    curr_enum_val = 0;                  /* Initialize Current Enum Value */
    fp = freopen(name, "r", stdin);     /* Remap Standard Input to Input File. 
*/
    ASSERT( fp, "Structure File Not Found" );
    printf("Loading Structure File = %s\n", name);
    retValue = (stl_t *)sdfparse();
    fclose(fp);
    return(retValue);
}

/* Return Enum Value. Generates Assertion failure, if the enum is
   not found. 
*/
unsigned int enum_val ( enl_t *enl  /* Enum Name */  )
{
    printf("Enum Val\n");
    return 0xff;
}

/* 
Add Enum Value to the Enum Hash Table 
*/
void enum_add ( enl_t *enl,unsigned int value )
{
    printf("Added Enum value :%d Add\n",value);
}

/* 
Add Enum Value to the Enum Hash Table 
*/
void show_stl(stl_t *root)
{
    stl_t       *pNext_symb,
                *pNext_node;

    pNext_node = root;
    while(pNext_node)
     {
        printf("Structure = %s\n", pNext_node -> name);
        pNext_symb = pNext_node -> next_symb;
        while (pNext_symb)
         {
            printf("type id=%d - count =%d\n",pNext_symb -> value, pNext_symb 
-> count);
            pNext_symb = pNext_symb -> next_symb;
         }
        pNext_node = pNext_node -> next_node;
     }
}


reply via email to

[Prev in Thread] Current Thread [Next in Thread]