feat: update tokens
This commit is contained in:
parent
db863b806e
commit
102b68fc27
75
DragonLisp.l
75
DragonLisp.l
|
|
@ -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(); }
|
};
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
|
||||||
66
DragonLisp.y
66
DragonLisp.y
|
|
@ -41,78 +41,36 @@ namespace DragonLisp {
|
||||||
%define parse.assert
|
%define parse.assert
|
||||||
|
|
||||||
%token
|
%token
|
||||||
LE "<="
|
LESS_EQUAL "<="
|
||||||
GE ">="
|
GREATER_EQUAL ">="
|
||||||
|
LESS "<"
|
||||||
|
GREATER ">"
|
||||||
|
NOT_EQUAL "/="
|
||||||
EQUAL "="
|
EQUAL "="
|
||||||
NE "/="
|
|
||||||
LT "<"
|
|
||||||
GT ">"
|
|
||||||
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 <int64_t> INTEGER "integer"
|
||||||
%token <std::string> STRING "string"
|
%token <std::string> STRING "string"
|
||||||
|
%token <std::string> IDENTIFIER "identifier"
|
||||||
%type <DragonLisp::Token> basic_operator
|
|
||||||
%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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
17
token.h
17
token.h
|
|
@ -4,17 +4,22 @@
|
||||||
namespace DragonLisp {
|
namespace DragonLisp {
|
||||||
|
|
||||||
enum Token {
|
enum Token {
|
||||||
LE,
|
STRING,
|
||||||
GE,
|
SPACE,
|
||||||
|
FLOAT,
|
||||||
|
INTEGER,
|
||||||
|
LESS_EQUAL,
|
||||||
|
GREATER_EQUAL,
|
||||||
|
LESS,
|
||||||
|
GREATER,
|
||||||
|
NOT_EQUAL,
|
||||||
EQUAL,
|
EQUAL,
|
||||||
NE,
|
LPAREN,
|
||||||
LT,
|
RPAREN,
|
||||||
GT,
|
|
||||||
PLUS,
|
PLUS,
|
||||||
MINUS,
|
MINUS,
|
||||||
MULTIPLY,
|
MULTIPLY,
|
||||||
DIVIDE,
|
DIVIDE,
|
||||||
STRING,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue