Skip to content

Instantly share code, notes, and snippets.

@kaushiks
Last active December 23, 2022 17:06
Show Gist options
  • Save kaushiks/ad4d28673dadd5577e13 to your computer and use it in GitHub Desktop.
Save kaushiks/ad4d28673dadd5577e13 to your computer and use it in GitHub Desktop.
A reentrant C++ flex scanner.
%option reentrant
%option noyywrap
%option extra-type="Scanner *"
%option header-file="flex-scanner.h"
%option outfile="flex-scanner.c"
%{
#include <cstdio>
#include "scanner.hpp"
%}
%%
[ \t\n] {
}
[0-9]+\.[0-9]+ {
printf("FLOAT: %s\n", yytext);
}
[0-9]+ {
printf("INTEGER: %s\n", yytext);
}
[a-zA-Z_]+[a-zA-Z0-9_]* {
printf("IDENTIFIER: %s\n", yytext);
}
. {
fprintf(stderr, "Unexpected token: %s\n", yytext);
}
class Scanner;
#include <cstdio>
#include "flex-scanner.h"
#include "scanner.hpp"
int main(int argc, const char *argv[])
{
do {
char input[80] = {0};
printf(">>> ");
if (fgets(input, 80, stdin)) {
do {
Scanner *scanner = Scanner::create(input);
scanner->scan();
} while (0);
}
} while (1);
return 0;
}
all:
flex flex-scanner.l
g++ -o d flex-scanner.c scanner.cc main.cc
test: all
./d
clean:
rm ./d
rm ./flex-scanner.c
rm ./flex-scanner.h

A reentrant C++ flex scanner.

class Scanner;
#include "flex-scanner.h"
#include "scanner.hpp"
Scanner*
Scanner::create(const char* string)
{
Scanner* self = NULL;
yyscan_t flex;
YY_BUFFER_STATE buffer;
if (string) {
yylex_init(&flex);
buffer = yy_scan_string(string, flex);
self = new Scanner(flex, buffer);
yyset_extra(self, flex);
}
return self;
}
Scanner::Scanner(yyscan_t flex, YY_BUFFER_STATE buffer)
: _flex(flex),
_buffer(buffer)
{
}
Scanner::~Scanner()
{
yy_delete_buffer(_buffer, _flex);
yylex_destroy(_flex);
}
void
Scanner::scan()
{
yylex(_flex);
}
#pragma once
class Scanner {
public:
static Scanner* create(const char* string);
void scan();
~Scanner();
private:
Scanner(yyscan_t flex, YY_BUFFER_STATE buffer);
yyscan_t _flex;
YY_BUFFER_STATE _buffer;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment