0
votes

When I'm trying to check the expression "boolean x;" I'm getting "syntax error" and I can't understand why. When I'm checking the expression "x = 3;" or "2 = 1;", the abstract syntax tree is generated and no errors are presented. (I'm not allowed to use anything beside Lex and Yacc in this project and I'm using Ubuntu)

Lex file:

%%
[\n\t ]+; 
boolean {return BOOL;}
TRUE {return TRUE;}
FALSE {return FALSE;}
[0-9]+ {return NUM;}
[a-zA-Z][0-9a-zA-Z]* {return ID;}
. {return yytext[0];}
%%

Yacc file:

%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node{
    struct node *left;
    struct node *right;
    char *token;
    } node;
node *mknode(node *left, node *right, char *token);
void printtree(node *tree);
#define YYSTYPE struct node *
%}
%start code
%token ID,NUM,TRUE,FALSE,BOOL
%right '='
%%

code:lines{printtree($1); printf("\n");}
lines:calcExp';'|assignExp';'|boolExp ';'{$$ = $1;}
boolExp: boolST id{$$=$2;} 
calcExp: number '+' number {$$ = mknode($1,$3,"+");}
assignExp: id '=' number{$$ = mknode($1,$3,"=");}
boolSt : BOOL;
id : ID {$$ = mknode(0,0,yytext);}
number : NUM{$$ = mknode(0,0,yytext);}

%%
#include "lex.yy.c"
int main (void) {return yyparse();}

node *mknode(node *left, node *right, char *token){
    node *newnode = (node *)malloc(sizeof(node));
    char *newstr = (char *)malloc(strlen(token)+1);
    strcpy(newstr, token);
    newnode->left = left;
    newnode->right = right;
    newnode->token = newstr;
    return newnode;
 }

void printtree(node *tree){
    if (tree->left || tree->right)
        printf("(");
    printf(" %s ", tree->token);
    if(tree->left)
        printtree(tree->left);
    if(tree->right)
        printtree(tree->right);
    if(tree->left || tree->right)
        printf(")");
}
void yyerror (char *s) {
    fprintf (stderr, "%s\n",s);}
1
spelling: is it "bool" or "boolean"?user2404501
oh sorry. I'm trying to check the expression "boolean x;"SophieVi
Please format this illegible mess.user207421
Start by fixing all of the warnings produced by yacc/bison. The most relevant one is "error: symbol boolST is used, but is not defined as a token and has no rules". (If you look closely, the rule boolSt: BOOL does not define the symbol boolST.) It's not clear to me why you feel you need a non-terminal here at all; you could have written boolExp: BOOL id. Or, if you had used %token BOOL "boolean", you could use the even more readable boolExp: "boolean" id.rici
@sophievi: a character class will match a character which is in the list of characters. [\n\t ] will match newline, tab or space. So will [ \n\t]. But [\n\t] only matches newline or tab. Your question has the correct character class, but fails for the reason noted by sepp2k. Nowhere do you indicate that you removed the space in the character class.rici

1 Answers

1
votes

The first step to debug syntax errors is to enable %error-verbose in the bison file. Now instead of just saying "syntax errors", it tells us there was an unexpected character after the boolean keyword when it expected an identifier.

So let's add a print statement to the . rule in the lexer that prints the matched character, so that we can see where it produces unexpected characters. Now we see that it prints a space, but spaces should have been ignored, right? So let's look at the rule that's supposed to do that:

[\n\t ]+;

If your editor has proper syntax highlighting for flex files, the problem should become apparent now: The ; is seen as part of the rule, not the action. That is, the rule matches white space, followed by a semicolon, instead of just matching white space.

So remove the semicolon and it should work.