error_404
error_404

Reputation: 25

Flex/Lex reading from a input file

I have a Lex program that reads if a given character is an alphabet or number. How to I take my inputs directly from a file. This is my simple program. Also what would be a good tutorial for Flex/Lex

%{
#include<stdio.h>
%}

%%

[a-zA-Z]+   printf("Token Type: STRINGLITERAL \n Value: [%s] ",yytext);
[0-9]+ printf("Token Type: INTLITERAL \n VALUE:[%s]", yytext);

.   printf("[%s] is not a word",yytext);


%%

int main(void)
{
    yylex();
    return 0;
}

Upvotes: 1

Views: 13660

Answers (3)

Miguel
Miguel

Reputation: 2219

You have to set the variable yyin to the file handler of the file you want to read.

My favorite tutorial on Flex and Bison is this one from aquamentus.

From that same tutorial, here you have a fragment on how to read from a file using Flex.

int main(){
  // open a file handle to a particular file:
  FILE *myfile = fopen("your_file", "r");
  // make sure it's valid:
  if (!myfile) {
    cout << "I can't open the file!" << endl;
    return -1;
  }
  // set lex to read from it instead of defaulting to STDIN:
  yyin = myfile;
  
  // lex through the input:
  while(yylex());
  fclose(myfile);
}

Upvotes: 2

Loki Astari
Loki Astari

Reputation: 264411

I Like the C++ output from flex.

Lexer.l

%option c++

%{

#include <string>
#include <iostream>

%}

WhiteSpace          [ \t]

%%

[A-Za-z]+           {std::cout << "WORD:  " << std::string(yytext, yyleng) << "\n";   return 1;}
[0-9]+              {std::cout << "Number:" << std::string(yytext, yyleng) << "\n";   return 2;}

{WhiteSpace}+       {/*IgnoreSpace*/}

.                   {std::cout << "Unknown\n";  return 3;}


%%

int yyFlexLexer::yywrap()
{
    return true;
}

Build Like this:

flex --header-file=Lexer.h -t Lexer.l  > Lexer.cpp

Note: I use the above line because I hate the generated files names and this way I get to use file names I like.

Now you can use standard C++ streams (like std::cin and std::ifstream).

#include "Lexer.h"

int main()
{
    yyFlexLexer   lex(&std::cin);  // Pass a pointer to any input stream.
    while (lex.yylex())
    {
    }

    std::ifstream  file("text");
    yyFlexLexer    anotherLexer(&file);

    while(anotherLexer.yylex())
    {
    }
}

Upvotes: 2

rm-ass
rm-ass

Reputation: 39

@KompjoeFriek, thanks for the link :)

@error_404, this code work for me

%{
    #include<stdio.h>
%}

%%
[a-zA-Z]+   printf("Token Type: STRINGLITERAL \n Value: [%s] ",yytext);
[0-9]+ printf("Token Type: INTLITERAL \n VALUE:[%s]", yytext);

.   printf("[%s] is not a word",yytext);
%%

int main(int ac, char **av)
{
    FILE    *fd;

    if (ac == 2)
    {
        if (!(fd = fopen(av[1], "r")))
        {
            perror("Error: ");
            return (-1);
        }
        yyset_in(fd);
        yylex();
        fclose(fd);
    }
    else
        printf("Usage: a.out filename\n");
    return (0);
}

Upvotes: 0

Related Questions