2
votes

I have a lex and yacc file to generate the abstract syntax tree for a given input. It works fine for the first lex input and then shows a yyerror() syntax error for the second input. (The input is right)

%{
    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    int yylex(void);
    #include "y.tab.h"
    struct tree
    {
        char *val;
        struct tree* left;
        struct tree* right;
    };
    struct tree* make(struct tree* left, char * , struct tree* right);
    void display(struct tree* );
%}

%union
{
    struct tree * node;
    char * sexy;
}

%token<sexy> INTEGER
%type<node> expr
%type<node> term
%type<sexy> factor

%%
line : 
    expr '\n' {display($1);}
    | '\n' 

expr : 
    expr '+' term { $$ = make($1,"+",$3);}
    | expr '-' term { $$ = make($1,"-",$3);}
    | term { $$ = $1; }

term : 
    term '*' factor { $$ = make($1,"*",$3);}
    | term '/' factor{ $$ = make($1,"/",$3);}
    | factor { $$ = $1 ;}

factor : 
    '(' expr ')'  { $$ = $2; }
    | INTEGER { $$ = make(NULL,$1,NULL);}
%%

struct tree* make (struct tree* lft, char * value , struct tree* rght)
{
    struct tree *temp=(struct tree*)malloc(sizeof(struct tree));
    char *str = malloc(strlen(value)+1);
    strcpy(str,value);
    temp->val=str;
    temp->right=rght;
    temp->left=lft;
    return (temp);
}

void display(struct tree * dis)
{
    int i;
    printf("Current node is : %s\n",dis->val);
    if(dis->left)
        printf("Left child is : %s\n",dis->left->val); 
    if(dis->right)
        printf("Right child is : %s\n\n",dis->right->val); 
    if(dis->left) 
        display(dis->left); 
    else 
        printf("Left child is empty\n");
    if(dis->right)
        display(dis->right);
    else 
        printf("Right child is empty\n\n");
}

Lex code given below

%{
        #include<stdio.h>
        #include "y.tab.h"
        int number=0,i=0;
    %}
    digit [0-9]
    letter [a-zA-z]
    id {letter}({letter}|{digit})*

    %%
    {digit}+ {yylval.sexy = yytext; return INTEGER;}
    [+-/*] {return *yytext;}
    "(" {return *yytext;}
    ")" {return *yytext;}
    \n {return *yytext;}
    %%

    void yyerror(char *str)
    {
     fprintf(stderr, "%s\n", str);
    }

    int main()
    {
        yyparse();
        return(0);
    }
1
Have the tree printed in yyerror to see how far it got.Paul Ogilvie
Please provide both inputs.Paul Ogilvie
It works I had to add another grammar rule in YACC to accommodate multiple input lines.Sahitya Sridhar

1 Answers

2
votes

Add another grammar rule in YACC to accommodate multiple input lines

program : 
    line program
    | line