stela/lexer.l

80 lines
2.2 KiB
Plaintext

%{
#include <iostream>
#include <cstdlib>
#include "lexer.hpp"
#include "interpreter.hpp"
#include "parser.hpp"
#include "location.hh"
// Original yyterminate() macro returns int. Since we're using Bison 3 variants
// as tokens, we must redefine it to change type from `int` to `Parser::semantic_type`
#define yyterminate() stela::Parser::make_END(stela::location());
// This will track current scanner location.
// Action is called when length of the token is known.
#define YY_USER_ACTION this->interpreter.increase_location(yyleng);
// !!!WARNING!!!
// Location API is used, but the location is not initialized, 'cause I'm lazy. When making
// a token with make_{something} method you can pass detailed token location. Current location
// is accessible with m_driver.location() method. All puzzle elements are there - just
// pass location value in every action code block below. I'm going to waste more time writing
// this excuse than putting this boilerplate below...
//
// Location class can be found in location.hh and posistion.hh files. It's just a bit too much
// boilerplate for this small example. Bummer.
%}
%option nodefault
%option noyywrap
%option c++
%option yyclass="Lexer"
%option prefix="stela_"
%%
[a-z]+ {
std::cout << "Scanner: identifier [" << yytext << "]\n";
return stela::Parser::make_STRING(yytext, stela::location( /* put location data here if you want */ ));
}
\( {
std::cout << "Scanner: '('\n";
return stela::Parser::make_LEFTPAR(stela::location());
}
\) {
std::cout << "Scanner: ')'\n";
return stela::Parser::make_RIGHTPAR(stela::location());
}
; {
std::cout << "Scanner: ';'\n";
return stela::Parser::make_SEMICOLON(stela::location());
}
, {
std::cout << "Scanner: ','\n";
return stela::Parser::make_COMMA(stela::location());
}
[\n\t ] {
//cout << "Scanner: whitechar (ignored)" << endl;
}
[1-9][0-9]* {
std::cout << "Scanner: decimal number: " << yytext << '\n';
uint64_t number = strtoull(yytext, 0, 10);
return stela::Parser::make_NUMBER(number, stela::location());
}
. {
std::cout << "Scanner: unknown character [" << yytext << "]\n";
}
<<EOF>> { return yyterminate(); }
%%