Generating a C++ reentrant lexer.

This commit is contained in:
Stefano Sanfilippo 2014-11-28 19:01:15 +01:00
parent 649797f13a
commit 5703593c9d
2 changed files with 92 additions and 62 deletions

View File

@ -1,19 +1,19 @@
%{ %{
#include "Monicelli.tab.hpp" #include "Scanner.hpp"
#include "Parser.hpp"
#include <string> #include <string>
#include <cstdlib> #include <cstdlib>
extern int lineNumber; static void meta(const char *);
void mcerror(const char *);
void mcmeta(const char *);
using namespace monicelli; using namespace monicelli;
typedef Parser::token token;
%} %}
%option noyywrap %option ecs stack warn c++
%option nounput %option nodefault noyywrap nounput yylineno
%option yyclass="Scanner"
DIGIT [0-9] DIGIT [0-9]
HEXDIGIT [0-9a-zA-Z] HEXDIGIT [0-9a-zA-Z]
@ -22,65 +22,61 @@ CHAR [a-zA-Z_]
%x shift %x shift
%% %%
<INITIAL,shift>("\r\n"|"\n") {
lineNumber += 1;
}
"#"[^\n]* { "#"[^\n]* {
mcmeta(yytext + 1); meta(yytext + 1);
} }
"bituma"[^\n]* {} "bituma"[^\n]* {}
"Lei ha clacsonato" { "Lei ha clacsonato" {
return MAIN; return token::MAIN;
} }
"vaffanzum" { "vaffanzum" {
return RETURN; return token::RETURN;
} }
"Necchi" { "Necchi" {
mclval.typeval = Type::INT; lval->typeval = Type::INT;
return TYPENAME; return token::TYPENAME;
} }
"Mascetti" { "Mascetti" {
mclval.typeval = Type::CHAR; lval->typeval = Type::CHAR;
return TYPENAME; return token::TYPENAME;
} }
"Perozzi" { "Perozzi" {
mclval.typeval = Type::FLOAT; lval->typeval = Type::FLOAT;
return TYPENAME; return token::TYPENAME;
} }
"Melandri" { "Melandri" {
mclval.typeval = Type::BOOL; lval->typeval = Type::BOOL;
return TYPENAME; return token::TYPENAME;
} }
"Sassaroli" { "Sassaroli" {
mclval.typeval = Type::DOUBLE; lval->typeval = Type::DOUBLE;
return TYPENAME; return token::TYPENAME;
} }
"conte" { "conte" {
return STAR; return token::STAR;
} }
"voglio" { "voglio" {
return VARDECL; return token::VARDECL;
} }
"come "("se ")?"fosse" { "come "("se ")?"fosse" {
return ASSIGN; return token::ASSIGN;
} }
("il"|"lo"|"la"|"l'"|"i"|"gli"|"le"|"un"|"un'"|"una"|"dei") { ("il"|"lo"|"la"|"l'"|"i"|"gli"|"le"|"un"|"un'"|"una"|"dei") {
return ARTICLE; return token::ARTICLE;
} }
"più" { "più" {
return OP_PLUS; return token::OP_PLUS;
} }
"meno" { "meno" {
return OP_MINUS; return token::OP_MINUS;
} }
"per" { "per" {
return OP_TIMES; return token::OP_TIMES;
} }
"diviso" { "diviso" {
return OP_DIV; return token::OP_DIV;
} }
"con scappellamento a" { "con scappellamento a" {
BEGIN(shift); BEGIN(shift);
@ -89,94 +85,100 @@ CHAR [a-zA-Z_]
BEGIN(INITIAL); BEGIN(INITIAL);
} }
<shift>"sinistra" { <shift>"sinistra" {
return OP_SHL; return token::OP_SHL;
} }
<shift>"destra" { <shift>"destra" {
return OP_SHR; return token::OP_SHR;
} }
"minore "("di"|"del") { "minore "("di"|"del") {
return OP_LT; return token::OP_LT;
} }
"maggiore "("di"|"del") { "maggiore "("di"|"del") {
return OP_GT; return token::OP_GT;
} }
"minore o uguale "("a"|"di") { "minore o uguale "("a"|"di") {
return OP_LTE; return token::OP_LTE;
} }
"maggiore o uguale "("a"|"di") { "maggiore o uguale "("a"|"di") {
return OP_GTE; return token::OP_GTE;
} }
"a posterdati" { "a posterdati" {
return PRINT; return token::PRINT;
} }
"mi porga" { "mi porga" {
return INPUT; return token::INPUT;
} }
"ho visto" { "ho visto" {
return ASSERT; return token::ASSERT;
} }
"!" { "!" {
return BANG; return token::BANG;
} }
"stuzzica" { "stuzzica" {
return LOOP_BEGIN; return token::LOOP_BEGIN;
} }
"e brematura anche, se" { "e brematura anche, se" {
return LOOP_CONDITION; return token::LOOP_CONDITION;
} }
"che cos'è" { "che cos'è" {
return BRANCH_CONDITION; return token::BRANCH_CONDITION;
} }
"?" { "?" {
return BRANCH_BEGIN; return token::BRANCH_BEGIN;
} }
"o tarapia tapioco" { "o tarapia tapioco" {
return BRANCH_ELSE; return token::BRANCH_ELSE;
} }
"e velocità di esecuzione" { "e velocità di esecuzione" {
return BRANCH_END; return token::BRANCH_END;
} }
":" { ":" {
return COLON; return token::COLON;
} }
"blinda la supercazzola" { "blinda la supercazzola" {
return FUNDECL; return token::FUNDECL;
} }
"con" { "con" {
return PARAMS; return token::PARAMS;
} }
"," { "," {
return COMMA; return token::COMMA;
} }
"brematurata la supercazzola" { "brematurata la supercazzola" {
return FUNCALL; return token::FUNCALL;
} }
"o scherziamo"("?")? { "o scherziamo"("?")? {
return FUN_END; return token::FUN_END;
} }
"avvertite don ulrico" { "avvertite don ulrico" {
return ABORT; return token::ABORT;
} }
"o magari" { "o magari" {
return CASE_END; return token::CASE_END;
} }
<INITIAL,shift>[ \t\f\v] {} <INITIAL,shift>[ \t\f\v\n\r] {}
{CHAR}({DIGIT}|{CHAR})* { {CHAR}({DIGIT}|{CHAR})* {
mclval.strval = new std::string(yytext); lval->strval = new std::string(yytext);
return ID; return token::ID;
} }
{DIGIT}+ { {DIGIT}+ {
mclval.intval = strtol(yytext, NULL, 10); lval->intval = strtol(yytext, NULL, 10);
return NUMBER; return token::NUMBER;
} }
<INITIAL,shift>. { <INITIAL,shift>. {
mcerror("Unexpected token");
return -1; return -1;
} }
%% %%
void meta(const char *text) {
while (*text != '\0' && *text == ' ') {
text += 1;
}
std::cerr << "META: " << text << std::endl;
}

28
Scanner.hpp Normal file
View File

@ -0,0 +1,28 @@
#ifndef SCANNER_HPP
#define SCANNER_HPP
#ifndef yyFlexLexerOnce
#include <FlexLexer.h>
#endif
#include "Parser.hpp"
namespace monicelli {
class Scanner: public yyFlexLexer {
public:
Scanner(std::istream &in): yyFlexLexer(&in), lval(nullptr) {}
int yylex(Parser::semantic_type *lval) {
this->lval = lval;
return yylex();
}
private:
int yylex();
Parser::semantic_type *lval;
};
} // monicelli
#endif