0
votes

I am attempting to create a lexical analyzer that will return the length of a token in a text file.

I have a text file with a single letter 'a' in it.

The following is my lex.l file

%option noyywrap 
%{
%}

/* regular definitions */
delim           [ \t\n]
ws              {delim}+
letter          [A-Za-z]
digit           [0-9]

%%

{ws}            {/* no action */}
letter          {return 1;}

%%

The following is the main program file that uses the YYText() and YYLeng() function.

#include <stdio.h>
#include <stdlib.h>
#include "lex.yy.cc"

using namespace std;

int OpenInputOutput(int argc, char *argv[], ifstream & lexerFIn, ofstream & lexerFOut)
{
// open input
if (argc > 1) {
    lexerFIn.open(argv[1]);
    if (lexerFIn.fail()) {
        cerr << "Input file cannot be opened\n";
        return 0;
        }
    }
else {
cerr << "Input file not specified\n";
return 0;
}

// open output
lexerFOut.open("Output.txt");
if (lexerFOut.fail()) {
    cerr << "Output file cannot be opened\n";
    return 0;
}
}

int main(int argc, char *argv[]) 
{
yyFlexLexer lexer; 
while (lexer.yylex() != 0) {
    cout << lexer.YYText() << endl;
    cout << lexer.YYLeng() << endl;
}
return 0; 
} 

When I run the program with the aforementioned text file, with the command ./a "sample.txt", it writes 'a' on a file. Why doesn't it cout YYText() or YYLeng() or write the length of the character in the output file?

3
Nowhere in your code do you take a file name as a command line argument. It ignores the "sample.txt" you passed it. - David Schwartz
Why on earth should it return 'a' and 1 from a file you've never opened anywhere in the program? - ssube
Are you sure you do not want to match {letter}? letter (without the braces) matches exactly that six-letter literal. - Tim Landscheidt
@TimLandscheidt, but why doesn't it return the length? - idealistikz

3 Answers

1
votes

You can only call YYText or YYLeng after the parser has matched a token. You can't call them before parsing anything. You're retrieving properties of a match that never happened.

It's the same problem as if you randomly retrieved the value of errno.

0
votes

The yylex() function will be reading from standard input unless you do something to make it work differently. So, it is waiting on you to type a letter or white space.

0
votes

yylex () only returns for actions that return VALUE; or on EOF. cout << lexer.YYText() << endl; & Co. is thus only executed for the input letter.

So you either need to move the output code to the scanner's actions or return VALUE; in every action. NB: In the latter case I don't know if the values of yytext/yylen are guaranteed to exist and be meaningful after returning to yylex ()'s caller.