%option c++
%option noyywrap

%{
#include <iostream>
#include <cstdlib>  // for exit()
using namespace std;

// Required declaration for C++ flex
int yylex();
%}

DIGIT    [0-9]
ID       [a-zA-Z_][a-zA-Z0-9_]*
KEYWORD  int|float|if|else|while|return

%%

{KEYWORD}           { cout << "Keyword: " << yytext << endl; }
{ID}                { cout << "Identifier: " << yytext << endl; }
{DIGIT}+            { cout << "Integer: " << yytext << endl; }
{DIGIT}+"."{DIGIT}+ { cout << "Float: " << yytext << endl; }
[+\-*/=]            { cout << "Operator: " << yytext << endl; }
[;,(){}]            { cout << "Punctuation: " << yytext << endl; }
[ \t\n]+            { /* ignore whitespace */ }
.                   { cerr << "Error: Unrecognized character '" << yytext << "'" << endl; }

%%

int main(int argc, char** argv) {
    if (argc > 1) {
        yyin = fopen(argv[1], "r");
        if (!yyin) {
            cerr << "Error: Cannot open file " << argv[1] << endl;
            return 1;
        }
    }
    
    yylex();
    
    if (argc > 1) {
        fclose(yyin);
    }
    
    return 0;
}