Search code examples
compiler-errorsbisonflex-lexeryacc

Integer token using flex and yacc


I am trying to identify an integer token using flex and yacc. This is my flex file syntax for integers.

%{
#include "main.h"
#include "y.tab.h"
#include <stdlib.h>
#include <string.h>
#define YYSTYPE char *
void yyerror(char *);
%}

code            "code"
special         ":"
turn            "turn"
send            "send"
on              "on"
pin             "pin"
for             "for"
num             "[0-9]+"

%%
{code}          {return CODE;}
{special}       {return SPECIAL; }
{turn}          {return OPRTURN;}
{send}          {return OPRSEND;}
{on}            {return OPRON;}
{pin}           {return PORT;}
{for}           {return FOR;}
{num}           { yylval.iValue = atoi(yytext); return INTEGER;}
%%

int yywrap(void) {
return 1;
}

in yacc file..

%{
    #include "main.h"
    #include <stdio.h>
    #include <stdarg.h>
    #include <stdlib.h>
//    char *name[10];

void  startCompiler();

/* prototypes */
nodeType *enm(char* c);
nodeType *opr(int oper,int nops,...);
nodeType *id(int i);
nodeType *con(int value);
nodeType *cmd(char *c);

void freeNode(nodeType *p);
int ex(nodeType *p);
int yylex(void);

void yyerror(char *s);
//int sym[26];                    /* symbol table */
%}

%union {
    int iValue;                 /* integer value */
    char sIndex;                /* symbol table index */
    char *str;                /* symbol table index */
    nodeType *nPtr;             /* node pointer */
};

%token <iValue> INTEGER

%token CODE SPECIAL OPRTURN OPRSEND OPRON PORT FOR
%type <nPtr> stmt stmt_list oper operation duration pin location



%%

input   : function { exit(0);}
        ;

input   : function { exit(0);}
        ;

function : function stmt  { ex($2); freeNode($2);}
        |
        ;

stmt    : 

        | PORT location          { printf("Port taken"); }
        ;


location : INTEGER  { printf("Number is %d",$1); }

                ;

but when I execute the program, it does not recognize the number,

Input is

pin 4

Output

4

Output should be

Port taken Number is 4

What am I missing here? All the other tokens are working fine.

Thanks in advance.


Solution

  • The output you get is the output from the yyerror function, which by default just prints invalid tokens to stderr.

    What happens is that "pin" is properly recognized, but "4" isn't. So the statement rule isn't producing any output because it's still waiting for an integer. So the only output is that of yyerror.

    The reason it doesn't recognize 4 is that you quoted the regex for numbers as a string literal. So it's looking for the literal string "[0-9]+". Remove the quotes to have it be interpreted as a regex.

    PS: You'll also want to add a rule that skips whitespace or else you'll have to input pin4 without spaces.