224 lines
4.0 KiB
Plaintext
224 lines
4.0 KiB
Plaintext
%{
|
|
/*
|
|
* Monicelli: an esoteric language compiler
|
|
*
|
|
* Copyright (C) 2014 Stefano Sanfilippo
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "Scanner.hpp"
|
|
#include "Parser.hpp"
|
|
|
|
#include <string>
|
|
|
|
static void meta(const char *);
|
|
|
|
using namespace monicelli;
|
|
typedef Parser::token token;
|
|
|
|
#define YY_USER_ACTION location->begin.columns(yyleng);
|
|
|
|
inline
|
|
bool in(const char *sub, const std::string &str) {
|
|
return str.find(sub) != std::string::npos;
|
|
}
|
|
|
|
%}
|
|
|
|
%option ecs stack warn c++
|
|
%option nodefault noyywrap nounput yylineno
|
|
%option yyclass="Scanner"
|
|
|
|
DIGIT [0-9]
|
|
HEXDIGIT [0-9a-zA-Z]
|
|
CHAR [a-zA-Z_]
|
|
|
|
%x shift
|
|
|
|
%%
|
|
|
|
"#"[^\n]* {
|
|
meta(yytext + 1);
|
|
}
|
|
|
|
"bituma"[^\n]* {}
|
|
|
|
"Lei ha clacsonato" {
|
|
return token::MAIN;
|
|
}
|
|
"vaffanzum" {
|
|
return token::RETURN;
|
|
}
|
|
"Necchi" {
|
|
lval->typeval = Type::INT;
|
|
return token::TYPENAME;
|
|
}
|
|
"Mascetti" {
|
|
lval->typeval = Type::CHAR;
|
|
return token::TYPENAME;
|
|
}
|
|
"Perozzi" {
|
|
lval->typeval = Type::FLOAT;
|
|
return token::TYPENAME;
|
|
}
|
|
"Melandri" {
|
|
lval->typeval = Type::BOOL;
|
|
return token::TYPENAME;
|
|
}
|
|
"Sassaroli" {
|
|
lval->typeval = Type::DOUBLE;
|
|
return token::TYPENAME;
|
|
}
|
|
"conte" {
|
|
return token::STAR;
|
|
}
|
|
"voglio" {
|
|
return token::VARDECL;
|
|
}
|
|
"come "("se ")?"fosse" {
|
|
return token::ASSIGN;
|
|
}
|
|
("il"|"lo"|"la"|"l'"|"i"|"gli"|"le"|"un"|"un'"|"una"|"dei"|"delle") {
|
|
return token::ARTICLE;
|
|
}
|
|
"più" {
|
|
return token::OP_PLUS;
|
|
}
|
|
"meno" {
|
|
return token::OP_MINUS;
|
|
}
|
|
"per" {
|
|
return token::OP_TIMES;
|
|
}
|
|
"diviso" {
|
|
return token::OP_DIV;
|
|
}
|
|
"con scappellamento a" {
|
|
BEGIN(shift);
|
|
}
|
|
<shift>"per" {
|
|
BEGIN(INITIAL);
|
|
}
|
|
<shift>"sinistra" {
|
|
return token::OP_SHL;
|
|
}
|
|
<shift>"destra" {
|
|
return token::OP_SHR;
|
|
}
|
|
"minore "("di"|"del") {
|
|
return token::OP_LT;
|
|
}
|
|
"maggiore "("di"|"del") {
|
|
return token::OP_GT;
|
|
}
|
|
"minore o uguale "("a"|"di") {
|
|
return token::OP_LTE;
|
|
}
|
|
"maggiore o uguale "("a"|"di") {
|
|
return token::OP_GTE;
|
|
}
|
|
"a posterdati" {
|
|
return token::PRINT;
|
|
}
|
|
"mi porga" {
|
|
return token::INPUT;
|
|
}
|
|
"ho visto" {
|
|
return token::ASSERT;
|
|
}
|
|
"!" {
|
|
return token::BANG;
|
|
}
|
|
"stuzzica" {
|
|
return token::LOOP_BEGIN;
|
|
}
|
|
"e "("b"|"p")"rematura anche, se" {
|
|
return token::LOOP_CONDITION;
|
|
}
|
|
"che cos'è" {
|
|
return token::BRANCH_CONDITION;
|
|
}
|
|
"?" {
|
|
return token::BRANCH_BEGIN;
|
|
}
|
|
"o tarapia tapioco" {
|
|
return token::BRANCH_ELSE;
|
|
}
|
|
"e velocità di esecuzione" {
|
|
return token::BRANCH_END;
|
|
}
|
|
":" {
|
|
return token::COLON;
|
|
}
|
|
"blinda la supercazzola" {
|
|
return token::FUNDECL;
|
|
}
|
|
"con" {
|
|
return token::PARAMS;
|
|
}
|
|
"," {
|
|
return token::COMMA;
|
|
}
|
|
("b"|"p")"rematurata la supercazzola" {
|
|
return token::FUNCALL;
|
|
}
|
|
"o scherziamo"("?")? {
|
|
return token::FUN_END;
|
|
}
|
|
"avvertite don ulrico" {
|
|
return token::ABORT;
|
|
}
|
|
"o magari" {
|
|
return token::CASE_END;
|
|
}
|
|
|
|
<INITIAL,shift>"\n" {
|
|
location->begin.lines();
|
|
}
|
|
|
|
<INITIAL,shift>[ \t\f\v\r] {
|
|
}
|
|
|
|
{CHAR}({DIGIT}|{CHAR})* {
|
|
lval->strval = new std::string(yytext);
|
|
return token::ID;
|
|
}
|
|
|
|
[-+]?(({DIGIT}*".")?{DIGIT}+|{DIGIT}+".")([eE][-+]?{DIGIT}+)? {
|
|
std::string value(yytext);
|
|
|
|
if (in(".", value) || in("e", value) || in("E", value)) {
|
|
lval->floatval = std::stod(value);
|
|
return token::FLOAT;
|
|
} else {
|
|
lval->intval = std::stol(value);
|
|
return token::NUMBER;
|
|
}
|
|
}
|
|
|
|
<INITIAL,shift>. {
|
|
return token::ERROR;
|
|
}
|
|
|
|
%%
|
|
|
|
void meta(const char *text) {
|
|
while (*text != '\0' && *text == ' ') {
|
|
text += 1;
|
|
}
|
|
std::cerr << "META: " << text << std::endl;
|
|
}
|
|
|