feat: update tokens

This commit is contained in:
Eatswap 2022-12-10 19:16:19 +08:00
parent db863b806e
commit 102b68fc27
Signed by: Eatswap
GPG Key ID: BE661106A1F3FA0B
3 changed files with 85 additions and 95 deletions

View File

@ -20,8 +20,9 @@ using token = DragonLisp::DLParser::token;
%option yyclass="DragonLisp::DLScanner" %option yyclass="DragonLisp::DLScanner"
%option verbose backup warn noyywrap c++ nounistd debug noline %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]* id [a-zA-Z_][a-zA-Z_0-9]*
int [0-9]+
blank [ \t\v\r] blank [ \t\v\r]
comment ;.*$ comment ;.*$
string \"[^\r\n]*\" string \"[^\r\n]*\"
@ -47,32 +48,65 @@ string \"[^\r\n]*\"
{blank}+ { {blank}+ {
loc->step(); loc->step();
std::printf("Skipping blank\n"); std::printf("Skipping blank\n");
return token::TOKEN_SPACE;
}; };
\n+ { \n+ {
loc->lines(yyleng); loc->lines(yyleng);
loc->step(); loc->step();
std::printf("Skipping newline\n"); std::printf("Skipping newline\n");
return token::TOKEN_SPACE;
} }
{float} {
errno = 0;
char* seq_end_ptr = nullptr;
double n = strtod(yytext, &seq_end_str);
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"); std::printf("Scanned <=\n");
return token::TOKEN_LE; return token::TOKEN_LESS_EQUAL;
}; };
">=" { ">=" {
std::printf("Scanned >=\n"); std::printf("Scanned >=\n");
return token::TOKEN_GE; return token::TOKEN_GREATER_EQUAL;
}; };
"<" { "<" {
std::printf("Scanned <\n"); std::printf("Scanned <\n");
return token::TOKEN_LT; return token::TOKEN_LESS;
}; };
">" { ">" {
std::printf("Scanned >\n"); std::printf("Scanned >\n");
return token::TOKEN_GT; return token::TOKEN_GREATER;
};
"/=" {
std::printf("Scanned !=\n");
return token::TOKEN_NOT_EQUAL;
}; };
"=" { "=" {
@ -80,11 +114,6 @@ string \"[^\r\n]*\"
return token::TOKEN_EQUAL; return token::TOKEN_EQUAL;
}; };
"/=" {
std::printf("Scanned !=\n");
return token::TOKEN_NE;
};
"(" { "(" {
std::printf("Scanned (\n"); std::printf("Scanned (\n");
return token::TOKEN_LPAREN; return token::TOKEN_LPAREN;
@ -107,28 +136,26 @@ string \"[^\r\n]*\"
"*" { "*" {
std::printf("Scanned *\n"); std::printf("Scanned *\n");
return token::TOKEN_STAR; return token::TOKEN_MULTIPLY;
}; };
"/" { "/" {
std::printf("Scanned /\n"); std::printf("Scanned /\n");
return token::TOKEN_SLASH; return token::TOKEN_DIVIDE;
}; };
{int} { {id} {
errno = 0; std::printf("Scanned identifier: %s\n", yytext);
int64_t n = strtoll(yytext, nullptr, 10); yylval->emplace<std::string>(std::string(yytext, yyleng));
if (errno) return token::TOKEN_IDENTIFIER;
throw DragonLisp::DLParser::syntax_error(*loc, "Invalid integer provided: " + std::string(yytext));
yylval->emplace<int64_t>(n);
std::printf("Scanned integer: %lld\n", n);
return token::TOKEN_NUMBER;
}; };
{id} { /* return DragonLisp::DLParser::make_IDENTIFIER(yytext, *loc); */ } . {
throw DragonLisp::DLParser::syntax_error(*loc, "Invalid character: " + std::string(yytext));
};
. { throw DragonLisp::DLParser::syntax_error(*loc, "Invalid character: " + std::string(yytext)); } <<EOF>> {
yyterminate();
<<EOF>> { yyterminate(); } };
%% %%

View File

@ -41,78 +41,36 @@ namespace DragonLisp {
%define parse.assert %define parse.assert
%token %token
LE "<=" LESS_EQUAL "<="
GE ">=" GREATER_EQUAL ">="
EQUAL "=" LESS "<"
NE "/=" GREATER ">"
LT "<" NOT_EQUAL "/="
GT ">" EQUAL "="
LPAREN "(" LPAREN "("
RPAREN ")" RPAREN ")"
PLUS "+" PLUS "+"
MINUS "-" MINUS "-"
STAR "*" MULTIPLY "*"
SLASH "/" DIVIDE "/"
SPACE
; ;
%token END 0 "EOF" %token END 0 "EOF"
%token <int64_t> NUMBER "number" %token <double> FLOAT "float"
%token <std::string> STRING "string" %token <int64_t> INTEGER "integer"
%token <std::string> STRING "string"
%type <DragonLisp::Token> basic_operator %token <std::string> IDENTIFIER "identifier"
%type <DragonLisp::Token> arithmetic_operator
%type <DragonLisp::Token> comparsion_operator
%define parse.error verbose %define parse.error verbose
%% %%
S S
: R END : END
R
:
| R S-Expr
| STRING { std::cout << "Scanned string -> " << $1 << std::endl; }
S-Expr
: LPAREN basic_operator NUMBER NUMBER RPAREN {
std::printf("Operator -> %d, LHS -> %lld, RHS -> %lld\n", int($2), $3, $4);
std::printf("This is S-Expr!\n");
}
;
basic_operator
: arithmetic_operator { $$ = $1; }
| comparsion_operator { $$ = $1; }
;
arithmetic_operator
: PLUS { $$ = Token::PLUS; std::printf("I am plus +\n"); }
| MINUS { $$ = Token::MINUS; std::printf("I am minus -\n"); }
| STAR { $$ = Token::MULTIPLY; std::printf("I am star *\n"); }
| SLASH { $$ = Token::DIVIDE; std::printf("I am slash /\n"); }
;
comparsion_operator
: LE { $$ = Token::LE; }
| LT { $$ = Token::LT; }
| GE { $$ = Token::GE; }
| GT { $$ = Token::GT; }
| EQUAL { $$ = Token::EQUAL; }
| NE { $$ = Token::NE; }
%% %%
void DragonLisp::DLParser::error(const location_type& l, const std::string& msg) { void DragonLisp::DLParser::error(const location_type& l, const std::string& msg) {
std::cerr << "Error: " << msg << " at " << l << "\n"; std::cerr << "Error: " << msg << " at " << l << "\n";
} }
DragonLisp::DLParser::symbol_type make_NUMBER(const std::string& s, const DragonLisp::DLParser::location_type& loc) {
try {
int n = std::stoi(s);
return DragonLisp::DLParser::make_NUMBER(n, loc);
} catch (...) {
throw DragonLisp::DLParser::syntax_error(loc, "Invalid integer provided: " + s);
}
}

25
token.h
View File

@ -4,17 +4,22 @@
namespace DragonLisp { namespace DragonLisp {
enum Token { enum Token {
LE,
GE,
EQUAL,
NE,
LT,
GT,
PLUS,
MINUS,
MULTIPLY,
DIVIDE,
STRING, STRING,
SPACE,
FLOAT,
INTEGER,
LESS_EQUAL,
GREATER_EQUAL,
LESS,
GREATER,
NOT_EQUAL,
EQUAL,
LPAREN,
RPAREN,
PLUS,
MINUS,
MULTIPLY,
DIVIDE,
}; };
} }