Hello List,
I have written a parser in bison which works with flex
together. The compilation and execution work just fine
on machines with bison. I tried to port these in
a Sun OS where only yacc is installed
(version output> yacc: Software Generation Utilities (SGU) Solaris-ELF
(4.0) ). Unfortunately yacc stops compiling with: "identifier
redecleration" errors.
Here are the 2 errors:
[Mi Okt 01 05:53:06] [EMAIL PROTECTED] flexer >> make all
lex -t tokenizer.l > tokenizer.c
916/1000 nodes(%e), 2996/6000 positions(%p), 517/1000 (%n), 14588
transitions,
142/10000 packed char classes(%k), 1589/2000 packed transitions(%a),
1197/12000 output slots(%o)
cc -pedantic -g -c dar.c
yacc -t -d -b parser parser.y
mv parser.tab.h parser.h
mv parser.tab.c parser.c
cc -pedantic -g -o tokenizer.o -c tokenizer.c
cc -pedantic -g -o parser.o -c parser.c
"parser.y", line 66: identifier redeclared: YYSTYPE
current : union {int err_code, pointer to struct def_table {..}
def_tab, pointer to struct dec_table {..} dec_tab}
previous: union {int err_code, pointer to struct def_table {..}
def_tab, pointer to struct dec_table {..} dec_tab} : "parser.h", line 10
"parser.y", line 159: identifier redeclared: yylval
current : union {int err_code, pointer to struct def_table {..}
def_tab, pointer to struct dec_table {..} dec_tab}
previous: union {int err_code, pointer to struct def_table {..}
def_tab, pointer to struct dec_table {..} dec_tab} : "parser.h", line 11
cc: acomp failed for parser.c
*** Error code 2
make: Fatal error: Command failed for target `parser_compiling'
I have tried to solve the problem with the first error, deleting the
decleration which is on line 66 as specified in output, but I still get
the same error with the same line as I compile.
Now I suspect, errors are caused by one of those small differences
between yacc and bison. Yet I can't point out the cause. Therefore, I
decided to ask here even it's not specificly a yacc mailing
list(couldn't find it btw.)
I attach also the parser.y for further inspections.
Thanks in advance.
-Umut
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parser.h"
#include "table.h"
#include "dar.h"
int parse_file(char* filename) ;
static void yyerror(char* s) ;
int yylex(void);
#define YYERROR_VERBOSE
#define YY_DEBUG 1
#if YY_DEBUG
extern int yydebug ;
extern void init_tokenizer();
extern void print_def_table();
extern void print_dec_table();
extern void del_decl_from_table(struct dec_table* d_t_p) ;
extern struct dec_table* add_def_symbol(struct def_table* copy, node** p) ;
extern struct dec_table* add_dec_symbol(struct dec_table* copy, node** p, node*
vater);
extern struct dec_table** resolve_definition(unsigned char* s, int len);
extern int chk_dupl_dectbl(struct dec_table* t_p, node* vater) ;
extern void finit_rstck(void) ;
extern void push(node* node_p) ;
extern void push_troot(node* node_p) ;
extern void pop(void) ;
extern node* get_root(void) ;
extern node* lazy_create_node(lib_str label, lib_str name) ;
extern node* getnode_defsym_tbl(char* label);
extern node** get_def_node(unsigned char* s, int len) ;
extern void print_tree(node* vater);
extern void copy_dec2_defnode(node* def_node, lib_str src) ;
extern void define_node(node* source, node* target) ;
extern void copy_partial_tree(node* vater, node* src_tree, node** dst_tree) ;
extern node* tree_search_label(node* vater, lib_str label, short asn_type) ;
extern node* create_node(lib_str label, short asn_type, enum t_boolean
optional,
enum t_boolean is_root, long hi, long lo) ;
extern void bind_child(node** vater, node** child) ;
root_ops r_ops ;
void parse_error(int err_code);
node* local_root = NULL ;
int counter = 0 ;
#endif
%}
/* test */
%union {
int err_code ;
struct def_table* def_tab ;
struct dec_table* dec_tab ;
}
%start file
%token COMMENT_SIGN
%token WORD
%token NEW_LINE
%token DEFINITION_SIGN
%token <dec_tab>DECLERATION
%token <def_tab>OC_BRACK
%token CC_BRACK SEQLINEBRK
%token ROOT_LABEL
%token <dec_tab>ROOT_DECLR
%token <err_code>ERR_ROOT_DECL
%token <err_code>ERR_ROOT_NLINE
%token ERR_ROOT_ABSENCE ROOT_NLINE
%token <def_tab>INTEGER
%token <def_tab>ENUMERATED
%token <def_tab>BOOLEAN
%token <def_tab>OCTET_STRING
%token <def_tab>IA5STRING
%token <def_tab>UTF8STRING
%token <def_tab>SEQUENCE
%token <def_tab>CHOICE
%token CMPLX_COMMENT_SIGN CMPLX_WORD CMPLX_NLINE CMPLX_DSIGN CMPLX_CSIGN
%token <dec_tab>CMPLX_DECLERATION
%token <def_tab>CMPLX_INTEGER
%token <def_tab>CMPLX_ENUMERATED
%token <def_tab>CMPLX_BOOLEAN
%token <def_tab>CMPLX_OCTET_STRING
%token <def_tab>CMPLX_IA5STRING
%token <def_tab>CMPLX_RANGE
%token <def_tab>CMPLX_UTF8STRING
%token <def_tab>CMPLX_SEQUENCE
%token <def_tab>CMPLX_CHOICE
%token SDECL_NLINE
%token <err_code>ERR_SDECL_DUPL
%token <err_code>SDECL_ERROR
%token <err_code>ERR_INIT_DSIGN
%token <err_code>ERR_DECLR_WORD
%token <err_code>ERR_LABEL_NLINE
%token <err_code>ERR_SIMPL_DUPL
%token <err_code>ERR_SIMPL_BTYPE
%token <err_code>ERR_SIMPL_GEN
%token <err_code>ERR_DEFIN_WORD
%token <err_code>ERR_CMPLX_LABEL
%token <err_code>ERR_CMPLX_UNEXPECTED
%token <err_code>ERR_CMPLX_ROOT
%token <err_code>ERR_CMPLX_DEF
%token <err_code>ERR_CMPLX_DUPL
%token <err_code>ERR_CMPLX_TYPE
%type <def_tab>asn_base_type
%type <def_tab>asn_extendable_type
%type <def_tab>asn_complex_type
%type <def_tab>asn_complex_extendable
%type <err_code>error_types
%type <err_code>error_complex_root
%type <err_code>error_complex_types
%%
file: blocks { /* post operations */
struct dec_table* row_p ;
node** look_upp ;
int i ;
local_root = r_ops.get_root() ;
node* n_p2 = getnode_defsym_tbl("MegacoMessage") ;
// node* n_p = getnode_defsym_tbl("marie") ;
// node* n_p3 = getnode_defsym_tbl("Message") ;
/* debug stuff */
// if(local_root != NULL)
// printf("POST OPERATIONS: local_root:%.*s\n",
local_root->label.len, local_root->label.s ) ;
// else
// printf("POST OPERATIONS: local root is NULL\n") ;
/* 1. Check if declerations at 0 level exist,
* if yes try to bind them to vater, also delete from the
decl table */
/* 2. what to do if i have a definition of root which doesn't
match the one in
the definition table ? */
if(local_root == NULL){
printf("Warning root cannot be identified, add \"root
DECL_IDENT\" to \
your module file\n") ;
parse_error(ERR_ROOT_ABSENCE) ;
}
if(local_root->is_root==TRUE){
/* a root exists and we bind the node in decleration table
with father
"null" to it! Warning: There are no duplications of this
type */
for(row_p = begin ; row_p != NULL ; row_p = row_p->next){
if(row_p->node_p[0]->asn_type==0){
if( (look_upp = get_def_node(row_p->def_name.s,
row_p->def_name.len)) != NULL){
for(i=0 ; row_p->node_p[i] != NULL && i <
MAX_NODE_COPY ; i++)
define_node(*look_upp,
row_p->node_p[i]) ;
} else {
/*not defined, not bound, so we only bind it.
*/
if(row_p->vater == NULL) {
row_p->vater = local_root ;
bind_child(&local_root,
&(row_p->node_p[0]));
}
}
} else { /* */ }
/* defined but not yet bound, so we do it*/
if(row_p->vater == NULL){
bind_child(&local_root, &(row_p->node_p[0])) ;
printf("del_decl_from_table for:%.*s!\n",
row_p->label.len, row_p->label.s) ;
del_decl_from_table(row_p) ;
}
}
} else {
}
print_dec_table();
print_def_table();
print_tree(n_p2);
// print_tree(n_p);
// print_tree(n_p3) ;
}
;
blocks: asn_simple_block {/* */ }
|asn_simple_block SEQLINEBRK blocks {/* */ }
| asn_simple_block comment_block blocks {/* */ }
| ERR_INIT_DSIGN blocks {parse_error($1);}
| root_block blocks
;
root_block: ROOT_LABEL ROOT_DECLR ROOT_NLINE{
node** node_pp, * node_p ;
local_root = r_ops.get_root() ;
// printf("root found it has been defined as:%.*s\n",
(*node_pp)->label.len, (*node_pp)->label.s) ;
/* root's definition name is found in the list */
if( (node_pp = get_def_node($2->def_name.s, $2->def_name.len))
!= NULL){
(*node_pp)->is_root = TRUE ;
if(local_root == NULL)
r_ops.push(*node_pp) ;
else printf("Warning: Root already has been declared:
%.*s?\n",
local_root->label.len, local_root->label.s) ;
} else {
/* root's definition name not found in the list */
node* virt_root = NULL ;
node_p = lazy_create_node($2->label, $2->def_name) ;
node_p->is_root = TRUE ;
r_ops.push(node_p) ;
add_dec_symbol($2, &node_p, virt_root) ;
}
/* resolve_definition()*/
}
| ROOT_LABEL error_types {parse_error($2); }
;
comment_block: COMMENT_SIGN comment_words NEW_LINE
| COMMENT_SIGN NEW_LINE
;
comment_words: WORD | WORD comment_words ;
asn_simple_block: asn_complex_block
| WORD ERR_LABEL_NLINE asn_simple_block {parse_error($2);}
| WORD ERR_DECLR_WORD asn_simple_block { parse_error($2); }
| WORD DEFINITION_SIGN asn_base_type NEW_LINE {
int i ;
node* node_p = create_node($3->label, $3->asn_type, FALSE,
FALSE, $3->lo, $3->hi) ;
add_def_symbol($3, &node_p) ;
struct dec_table** d_t, **t_pp ;
d_t = resolve_definition(node_p->label.s,
node_p->label.len);
for(t_pp = d_t ; *t_pp != NULL ; t_pp++){
for(i=0; (*t_pp)->node_p[i] != NULL ; i++ ){
define_node(node_p, (*t_pp)->node_p[i]) ;
}
/* declerations at level 0(or with vater NULL), "label
def_name" are left
* in the list until the post operations. They will be
first cleaned up
* at that procedure */
if((*t_pp)->vater != NULL)
del_decl_from_table(*t_pp) ;
}
} asn_simple_block
| WORD DECLERATION SDECL_NLINE {
local_root = r_ops.get_root()/* root level = 0 */;
node *lazy_p, ** lookupp;
struct dec_table* t_p = NULL ;
/* check if label of decleration is duplicated at belonging
level*/
if( chk_dupl_dectbl($2, local_root) != 0 ) {
parse_error(ERR_SDECL_DUPL);
} else {
/* check type for decleration, if yes then
* copy decleration label to the definition node */
lazy_p = lazy_create_node($2->label, $2->def_name) ;
/* check if we have a definition for this root level
decleration
* if yes, copy_partial_tree overtakes every op. At
this point
* the decleration can only be binded to the big root
*/
if( (lookupp = get_def_node($2->def_name.s,
$2->def_name.len)) != NULL){
copy_partial_tree(NULL, *lookupp, &lazy_p) ;
// PRINT_NODE(lazy_p) ;
if(local_root == NULL) {
t_p = add_dec_symbol($2, &lazy_p, NULL) ;
} else{
lookupp = get_def_node(local_root->label.s,
local_root->label.len) ;
bind_child(lookupp, &lazy_p) ;
}
} else {
t_p = add_dec_symbol($2, &lazy_p, NULL) ;
if(local_root != NULL) {
lookupp = get_def_node(local_root->label.s,
local_root->label.len) ;
bind_child(lookupp, &lazy_p) ;
if(t_p != NULL) del_decl_from_table(t_p) ;
}
}
/* at this point we know that there exist a root
decleration.
* is it fully defined also? If only yes, the
decleration node
* can be bound */
}
}asn_simple_block
| WORD simple_dec_errors asn_simple_block
| WORD DECLERATION simple_dec_errors asn_simple_block
| WORD error_types DECLERATION NEW_LINE asn_simple_block {
parse_error($2); }
| WORD DECLERATION error_types NEW_LINE asn_simple_block {
parse_error($3); }
| WORD DEFINITION_SIGN asn_base_type ERR_SIMPL_DUPL
asn_simple_block {parse_error($4);}
| WORD DEFINITION_SIGN asn_base_type error_types
asn_simple_block{parse_error($4);}
| WORD DEFINITION_SIGN error_types
asn_simple_block{parse_error($3);}
;
error_types: ERR_SIMPL_BTYPE
| ERR_SIMPL_GEN
| ERR_DEFIN_WORD
| ERR_DECLR_WORD
| ERR_ROOT_DECL
| ERR_ROOT_NLINE
| ERR_SIMPL_GEN error_types
| ERR_SIMPL_BTYPE error_types
| ERR_DEFIN_WORD error_types
| ERR_DECLR_WORD error_types
| ERR_ROOT_DECL error_types
| ERR_ROOT_NLINE error_types
;
simple_dec_errors: ERR_SDECL_DUPL
| SDECL_ERROR
| ERR_SDECL_DUPL simple_dec_errors
| SDECL_ERROR simple_dec_errors
error_complex_types: ERR_CMPLX_LABEL
| ERR_CMPLX_DEF
| ERR_CMPLX_UNEXPECTED
| ERR_CMPLX_TYPE
| ERR_CMPLX_LABEL error_complex_types
| ERR_CMPLX_DEF error_complex_types
| ERR_CMPLX_UNEXPECTED error_complex_types
| ERR_CMPLX_TYPE error_complex_types
;
complex_words: CMPLX_WORD | CMPLX_WORD complex_words ;
asn_complex_block: {/* */ }
| CMPLX_NLINE asn_complex_block {/* */ }
| error_complex_root asn_complex_block { parse_error($1); }
| CMPLX_CSIGN complex_words CMPLX_NLINE asn_complex_block
{/*comment in complex*/}
| CMPLX_WORD error_complex_types asn_complex_block {
parse_error($2);}
| CMPLX_WORD CMPLX_DSIGN asn_complex_type {
/* definition section */
}asn_complex_block
| CMPLX_WORD CMPLX_DECLERATION {
node** t_pp, * node_p ;
/* decleration as "mess Message" */
local_root = r_ops.get_root() ;
if( chk_dupl_dectbl($2, local_root) != 0)
parse_error(ERR_SDECL_DUPL) ;
node_p = lazy_create_node($2->label, $2->def_name);
if( (t_pp = get_def_node($2->def_name.s,
$2->def_name.len)) != NULL )
copy_partial_tree(NULL, *t_pp, &node_p ) ; //
define_node(t_p, node_p) ;
else
add_dec_symbol($2, &node_p, local_root) ;
if(local_root != NULL) bind_child(&local_root, &node_p)
;
else printf("Warning from bison! Logical Failure\n");
} asn_complex_block
| CMPLX_WORD CMPLX_DSIGN error_complex_types asn_complex_block
{ parse_error($3); }
| CMPLX_WORD error_complex_types CMPLX_DECLERATION
asn_complex_block {parse_error($2);}
| CMPLX_WORD CMPLX_DSIGN asn_complex_type error_complex_types
asn_complex_block {
parse_error($4);
}
| CMPLX_WORD asn_complex_type CMPLX_RANGE{
node* search_p = NULL;
local_root = r_ops.get_root() ;
if( (search_p = tree_search_label(local_root,
$2->label, $2->asn_type))==NULL){
search_p = create_node($2->label, $2->asn_type,
FALSE, FALSE, $2->lo, $2->hi) ;
bind_child(&local_root, &search_p) ;
} else {
printf("there is already a node %.*s at %.*s
level, not adding\n",
search_p->label.len, search_p->label.s,
local_root->label.len,
local_root->label.s) ;
}
}asn_complex_block
| CMPLX_WORD asn_complex_type {
}asn_complex_block
| CMPLX_WORD asn_complex_extendable OC_BRACK {
/* pre recursive complex environment ops */
node* node_p = create_node($2->label, $2->asn_type,
FALSE, FALSE, $2->lo, $2->hi);
r_ops.push(node_p) ;
}asn_complex_block CC_BRACK{
/* post recursive complex environment ops */
node* search_res, *t_p ;
node* complex_child = r_ops.get_root() ; /*gets the one
upper root */
r_ops.pop() ; /* clean the node from roots list */
t_p = r_ops.get_root() ;
if( (search_res = tree_search_label(t_p,
complex_child->label, complex_child->asn_type))==NULL){
bind_child(&t_p, &complex_child) ;
}
// printf("complex block closed his local_root:%.*s\n",
t_p->label.len, t_p->label.s) ;
}asn_complex_block
| CMPLX_WORD CMPLX_DSIGN asn_complex_extendable CMPLX_NLINE
asn_complex_block
| CMPLX_WORD CMPLX_DSIGN asn_complex_extendable OC_BRACK
asn_complex_block CC_BRACK asn_complex_block
| WORD DEFINITION_SIGN asn_extendable_type OC_BRACK {
/* pre complex environment ops */
node* node_p = create_node($4->label, $4->asn_type,
FALSE, FALSE, $4->lo, $4->hi) ;
r_ops.push(node_p) ;
local_root = r_ops.get_root() ;
/* add to the definition list */
add_def_symbol($4, &node_p);
} asn_complex_block CC_BRACK {
/* post complex environment operations */
int i ;
struct dec_table** d_t = NULL ;
struct dec_table** t_pp = NULL;
local_root = r_ops.get_root() ;
const char* lit_root = "root" ;
/* check decleration table for the definition name */
d_t = resolve_definition(local_root->label.s,
local_root->label.len);
for(t_pp = d_t ; *t_pp != NULL ; t_pp++){
/* if root decleration has been found */
if((*t_pp)->vater == NULL &&
strncmp((char *)(*t_pp)->label.s, lit_root,
(*t_pp)->label.len)==0){
local_root->is_root = TRUE ;
r_ops.push_troot(local_root) ;
}else {
for(i=0; (*t_pp)->node_p[i] != NULL ; i++ ){
copy_partial_tree(NULL, local_root,
&((*t_pp)->node_p[i]) );
}
}
del_decl_from_table(*t_pp) ;
}
free(d_t) ; /* must free the allocated list */
r_ops.pop() ;
}
; /* end of complex parse rules */
error_complex_root: ERR_CMPLX_ROOT
asn_base_type: INTEGER {/* printf(" hop there was a integer there, i
saw!\n");*/ }
| ENUMERATED
| BOOLEAN
| OCTET_STRING {/*printf(" haha octet string also matches!\n")*/}
| IA5STRING
| UTF8STRING
| asn_extendable_type
;
asn_extendable_type: SEQUENCE
| CHOICE
;
asn_complex_type: CMPLX_INTEGER {/*printf(" hop there was a integer there, i
saw!\n"); */}
| CMPLX_ENUMERATED
| CMPLX_BOOLEAN
| CMPLX_OCTET_STRING {/*printf(" haha octet string also
matches!\n")*/}
| CMPLX_IA5STRING
| CMPLX_UTF8STRING
;
asn_complex_extendable: CMPLX_SEQUENCE
| CMPLX_CHOICE
;
%%
extern FILE* yyin ;
int parse_file(char* filename){
FILE* file_stream ;
if( (file_stream = fopen(filename, "r")) == NULL){
printf("File cannot be opened. Halt\n") ;
}
yyin = file_stream ;
while(!feof(yyin)) { yyparse() ; } /* liest eine zeile und das war's! */
return EXIT_SUCCESS ;
}
static void yyerror(char *s){
// printf("Line %d: Char %d: %s (last token was '%s')\n",
// lineno, charno, s, yytext) ;
printf("(last token was '%s')\n", s) ;
}
int main(void){
r_ops.init_rstack = finit_rstck ;
r_ops.push = push ;
r_ops.push_troot = push_troot ;
r_ops.pop = pop ;
r_ops.get_root = get_root ;
asn_mod_root = NULL ;
init_tokenizer();
r_ops.init_rstack() ;
parse_file("simple.txt") ;
return EXIT_SUCCESS ;
}
void parse_error(int type){
switch(type){
case ERR_INIT_DSIGN:
printf("a stand alone ::= is found, exitting\n");
break ;
case ERR_DECLR_WORD :
printf("Special decleration keyword is different than base type
and \
must be followed by newline, exitting.\n");
break ;
case ERR_LABEL_NLINE:
printf("no decleration found after label, exitting\n");
break ;
case ERR_SIMPL_DUPL:
printf("Duplicated labels, quitting\n");
break ;
case ERR_SDECL_DUPL:
printf("Duplicated decleration labels, quitting\n");
break ;
case ERR_SIMPL_BTYPE:
printf("Only one base type is allowed\n");
break ;
case ERR_SIMPL_GEN:
printf("After base type should a newline follow, quitting\n");
break ;
case ERR_DEFIN_WORD:
printf("Definition is followed by a base type and nothing else,
quitting\n");
break ;
case ERR_CMPLX_LABEL:
printf("No use of more than one label in cascaded environment
allowed, exitting.\n");
break;
case ERR_CMPLX_UNEXPECTED:
printf("No use of stand-alone decleration sign in casc. env
allowed, exitting\n");
break;
case ERR_CMPLX_DEF:
printf("No use of more than one base/extendable types in
cascaded environment allowed, exitting.\n");
break;
case ERR_CMPLX_TYPE:
printf("No use of Base Type words in declerations,
quitting\n");
break ;
case ERR_ROOT_DECL:
printf("root has already being defined, quitting\n");
break;
case ERR_ROOT_ABSENCE:
printf("No root decleration has been found, quitting\n") ;
break;
case ERR_ROOT_NLINE:
printf("root has no identifier, quitting\n");
break;
case ERR_CMPLX_ROOT:
printf("root cannot be defined in recursive env.\n");
break;
default:
printf("have you forgotten to bridge? val:%d\n", type);
break ;
}
exit(0);
}
_______________________________________________
[email protected] http://lists.gnu.org/mailman/listinfo/help-bison