|
From: | Ali KATKAR |
Subject: | Parsing Problem |
Date: | Mon, 12 Aug 2002 12:12:36 +0300 |
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; } }
[Prev in Thread] | Current Thread | [Next in Thread] |