DragonLisp/DragonLisp.l

332 lines
5.8 KiB
Plaintext

%{
#include <cstdio>
#include <cstdint>
#include <iostream>
#include "DragonLispScanner.hh"
#undef YY_DECL
#define YY_DECL int DragonLisp::DLScanner::yylex(DragonLisp::DLParser::semantic_type* const lval, DragonLisp::DLParser::location_type* location, DragonLisp::DLDriver& drv)
using token = DragonLisp::DLParser::token;
#define yyterminate() return token::TOKEN_END;
#define YY_USER_ACTION loc->columns(yyleng);
%}
%option yyclass="DragonLisp::DLScanner"
%option verbose backup warn noyywrap c++ nounistd debug noline
float [+-]?[0-9]*[.][0-9]+([eE][+-][0-9]+)?
int [+-]?(0[xX][0-9A-Fa-f]*|0[0-7]+|[1-9][0-9]*)
id [a-zA-Z_][a-zA-Z_0-9]*
blank [ \t\v\r]
comment ;[^\n\r]*
string \"[^\r\n]*\"
and (and|AND)
or (or|OR)
not (not|NOT)
max (max|MAX)
min (min|MIN)
if (if|IF)
logand (logand|LOGAND)
logior (logior|LOGIOR)
logxor (logxor|LOGXOR)
lognor (lognor|LOGNOR)
logeqv (logeqv|LOGEQV)
mod (mod|MOD)
rem (rem|REM)
incf (incf|INCF)
decf (decf|DECF)
defvar (defvar|DEFVAR)
defun (defun|DEFUN)
print (print|PRINT)
loop (loop|LOOP)
setq (setq|SETQ)
quote (quote|QUOTE)
for (for|FOR)
in (in|IN)
from (from|FROM)
to (to|TO)
dotimes (dotimes|DOTIMES)
dolist (dolist|DOLIST)
do (do|DO)
defconstant (defconstant|DEFCONSTANT)
%%
%{
yylval = lval;
%}
{string} {
loc->step();
std::printf("Scanned string: %s\n", yytext);
yylval->emplace<std::string>(std::string(yytext + 1, yyleng - 2));
return token::TOKEN_STRING;
}
{comment} {
std::printf("Scanned comment: %s\n", yytext);
loc->step();
}
{blank}+ {
loc->step();
std::printf("Skipping blank\n");
return token::TOKEN_SPACE;
};
\n+ {
loc->lines(yyleng);
loc->step();
std::printf("Skipping newline\n");
return token::TOKEN_SPACE;
}
{float} {
errno = 0;
char* seq_end_ptr = nullptr;
double n = strtod(yytext, &seq_end_ptr);
if (errno == ERANGE)
throw DragonLisp::DLParser::syntax_error(*loc, "Float out of range: " + std::string(yytext));
if (seq_end_ptr - yytext < yyleng)
throw DragonLisp::DLParser::syntax_error(*loc, "Invalid float scanned: [" + std::string(yytext, seq_end_ptr) + "], but provided [" + std::string(yytext) + "]");
yylval->emplace<double>(n);
std::printf("Scanned float: %lf\n", n);
return token::TOKEN_FLOAT;
}
{int} {
errno = 0;
char* seq_end_ptr = nullptr;
int64_t n = strtoll(yytext, &seq_end_ptr, 0);
if (errno == ERANGE)
throw DragonLisp::DLParser::syntax_error(*loc, "Integer out of range: " + std::string(yytext));
if (seq_end_ptr - yytext < yyleng)
throw DragonLisp::DLParser::syntax_error(*loc, "Invalid integer scanned: [" + std::string(yytext, seq_end_ptr) + "], but provided [" + std::string(yytext) + "]");
yylval->emplace<int64_t>(n);
std::printf("Scanned integer: %lld\n", n);
return token::TOKEN_INTEGER;
};
"<=" {
std::printf("Scanned <=\n");
return token::TOKEN_LESS_EQUAL;
};
">=" {
std::printf("Scanned >=\n");
return token::TOKEN_GREATER_EQUAL;
};
"<" {
std::printf("Scanned <\n");
return token::TOKEN_LESS;
};
">" {
std::printf("Scanned >\n");
return token::TOKEN_GREATER;
};
"/=" {
std::printf("Scanned !=\n");
return token::TOKEN_NOT_EQUAL;
};
"=" {
std::printf("Scanned =\n");
return token::TOKEN_EQUAL;
};
"(" {
std::printf("Scanned (\n");
return token::TOKEN_LPAREN;
};
")" {
std::printf("Scanned )\n");
return token::TOKEN_RPAREN;
};
"+" {
std::printf("Scanned +\n");
return token::TOKEN_PLUS;
};
"-" {
std::printf("Scanned -\n");
return token::TOKEN_MINUS;
};
"*" {
std::printf("Scanned *\n");
return token::TOKEN_MULTIPLY;
};
"/" {
std::printf("Scanned /\n");
return token::TOKEN_DIVIDE;
};
{and} {
std::printf("Scanned and\n");
return token::TOKEN_AND;
};
{or} {
std::printf("Scanned or\n");
return token::TOKEN_OR;
};
{not} {
std::printf("Scanned not\n");
return token::TOKEN_NOT;
};
{max} {
std::printf("Scanned max\n");
return token::TOKEN_MAX;
};
{min} {
std::printf("Scanned min\n");
return token::TOKEN_MIN;
};
{if} {
std::printf("Scanned if\n");
return token::TOKEN_IF;
};
{logand} {
std::printf("Scanned logand\n");
return token::TOKEN_LOGAND;
};
{logior} {
std::printf("Scanned logior\n");
return token::TOKEN_LOGIOR;
};
{logxor} {
std::printf("Scanned logxor\n");
return token::TOKEN_LOGXOR;
};
{lognor} {
std::printf("Scanned lognor\n");
return token::TOKEN_LOGNOR;
};
{logeqv} {
std::printf("Scanned logeqv\n");
return token::TOKEN_LOGEQV;
};
{mod} {
std::printf("Scanned mod\n");
return token::TOKEN_MOD;
};
{rem} {
std::printf("Scanned rem\n");
return token::TOKEN_REM;
};
{incf} {
std::printf("Scanned incf\n");
return token::TOKEN_INCF;
};
{decf} {
std::printf("Scanned decf\n");
return token::TOKEN_DECF;
};
{defvar} {
std::printf("Scanned defvar\n");
return token::TOKEN_DEFVAR;
};
{defun} {
std::printf("Scanned defun\n");
return token::TOKEN_DEFUN;
};
{print} {
std::printf("Scanned print\n");
return token::TOKEN_PRINT;
};
{loop} {
std::printf("Scanned loop\n");
return token::TOKEN_LOOP;
};
{setq} {
std::printf("Scanned setq\n");
return token::TOKEN_SETQ;
};
{quote} {
std::printf("Scanned quote\n");
return token::TOKEN_QUOTE;
};
{for} {
std::printf("Scanned for\n");
return token::TOKEN_FOR;
};
{in} {
std::printf("Scanned in\n");
return token::TOKEN_IN;
};
{from} {
std::printf("Scanned from\n");
return token::TOKEN_FROM;
};
{to} {
std::printf("Scanned to\n");
return token::TOKEN_TO;
};
{dotimes} {
std::printf("Scanned dotimes\n");
return token::TOKEN_DOTIMES;
};
{dolist} {
std::printf("Scanned dolist\n");
return token::TOKEN_DOLIST;
};
{do} {
std::printf("Scanned do\n");
return token::TOKEN_DO;
};
{id} {
std::printf("Scanned identifier: %s\n", yytext);
yylval->emplace<std::string>(std::string(yytext, yyleng));
return token::TOKEN_IDENTIFIER;
};
. {
throw DragonLisp::DLParser::syntax_error(*loc, "Invalid character: " + std::string(yytext));
};
<<EOF>> {
yyterminate();
};
%%