Generating a C++ reentrant lexer.
This commit is contained in:
parent
649797f13a
commit
5703593c9d
126
Monicelli.lpp
126
Monicelli.lpp
|
@ -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
28
Scanner.hpp
Normal 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
|
Reference in New Issue
Block a user