xo-tokenizer xo-reader: + bool literals + if-expr parsing
This commit is contained in:
parent
b0305ede55
commit
ce760bd5cf
30 changed files with 848 additions and 74 deletions
|
|
@ -60,6 +60,12 @@ namespace xo {
|
|||
|
||||
/** create invalid token (same as null ctor, but explicit) **/
|
||||
static token invalid() { return token(); }
|
||||
/** Create token representing a boolean literal from text @p txt
|
||||
* @p txt must be @c true or @c false
|
||||
**/
|
||||
static token bool_token(const std::string & txt) {
|
||||
return token(tokentype::tk_bool, txt);
|
||||
}
|
||||
/** Create token representing 64-bit signed integer literal parsed from decimal @p txt.
|
||||
* The string @p txt must be a decimal integer literal, since @ref i64_value re-parses @p txt.
|
||||
**/
|
||||
|
|
@ -132,6 +138,8 @@ namespace xo {
|
|||
static token lambda() { return token(tokentype::tk_lambda); }
|
||||
/** token representing keyword @c if **/
|
||||
static token if_token() { return token(tokentype::tk_if); }
|
||||
/** token representing keyword @c else **/
|
||||
static token else_token() { return token(tokentype::tk_else); }
|
||||
/** token representing keyword @c let **/
|
||||
static token let() { return token(tokentype::tk_let); }
|
||||
/** token representing keyword @c in **/
|
||||
|
|
@ -165,10 +173,13 @@ namespace xo {
|
|||
|| tk_type_ == tokentype::tk_string
|
||||
|| tk_type_ == tokentype::tk_symbol); }
|
||||
|
||||
/** expect input matching @c "[+|-][0-9][0-9]*" **/
|
||||
/** expect input matching @c true or @c false **/
|
||||
bool bool_value() const;
|
||||
|
||||
/** expect input matching @c [+|-][0-9][0-9]* **/
|
||||
std::int64_t i64_value() const;
|
||||
|
||||
/** expect input matching @c "[+|-][0-9]*[.][0-9]*[e|E][+|-][0-9]*" **/
|
||||
/** expect input matching @c [+|-][0-9]*[.][0-9]*[e|E][+|-][0-9]* **/
|
||||
double f64_value() const;
|
||||
|
||||
/** print human-readable token representation on stream @p os **/
|
||||
|
|
@ -196,6 +207,29 @@ namespace xo {
|
|||
///@}
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
bool
|
||||
token<CharT>::bool_value() const {
|
||||
if (tk_type_ != tokentype::tk_bool) {
|
||||
throw (std::runtime_error
|
||||
(tostr("token::bool_value",
|
||||
": token with type tk found where tk_bool expected",
|
||||
xtag("tk", tk_type_))));
|
||||
}
|
||||
|
||||
if (text_ == "true")
|
||||
return true;
|
||||
if (text_ == "false")
|
||||
return false;
|
||||
|
||||
throw (std::runtime_error
|
||||
(tostr("token::bool_value",
|
||||
": unexpected input string tk_bool token",
|
||||
xtag("text", text_))));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
std::int64_t
|
||||
token<CharT>::i64_value() const {
|
||||
|
|
|
|||
|
|
@ -479,9 +479,6 @@ namespace xo {
|
|||
(error_type(__FUNCTION__ /*src_function*/,
|
||||
"expecting key following escape character \\",
|
||||
input_state_,
|
||||
//current_line_,
|
||||
//current_pos_,
|
||||
//initial_whitespace,
|
||||
(ix - tk_start)));
|
||||
}
|
||||
|
||||
|
|
@ -511,9 +508,6 @@ namespace xo {
|
|||
(error_type(__FUNCTION__ /*src_function*/,
|
||||
"expecting one of n|r|\"|\\ following escape \\",
|
||||
input_state_,
|
||||
//current_line_,
|
||||
//current_pos_,
|
||||
//initial_whitespace,
|
||||
(ix - tk_start)));
|
||||
}
|
||||
break;
|
||||
|
|
@ -531,9 +525,6 @@ namespace xo {
|
|||
(error_type(__FUNCTION__ /*src_function*/,
|
||||
"missing terminating '\"' to complete literal string",
|
||||
input_state_,
|
||||
//current_line_,
|
||||
//current_pos_,
|
||||
//initial_whitespace,
|
||||
(ix - tk_start)));
|
||||
}
|
||||
|
||||
|
|
@ -683,7 +674,10 @@ namespace xo {
|
|||
|
||||
bool keep_text = false;
|
||||
|
||||
if (tk_text == "type") {
|
||||
if ((tk_text == "true") || (tk_text == "false")) {
|
||||
tk_type = tokentype::tk_bool;
|
||||
keep_text = true;
|
||||
} else if (tk_text == "type") {
|
||||
tk_type = tokentype::tk_type;
|
||||
} else if (tk_text == "def") {
|
||||
tk_type = tokentype::tk_def;
|
||||
|
|
@ -691,6 +685,10 @@ namespace xo {
|
|||
tk_type = tokentype::tk_lambda;
|
||||
} else if (tk_text == "if") {
|
||||
tk_type = tokentype::tk_if;
|
||||
} else if (tk_text == "then") {
|
||||
tk_type = tokentype::tk_then;
|
||||
} else if (tk_text == "else") {
|
||||
tk_type = tokentype::tk_else;
|
||||
} else if (tk_text == "let") {
|
||||
tk_type = tokentype::tk_let;
|
||||
} else if (tk_text == "in") {
|
||||
|
|
@ -842,9 +840,6 @@ namespace xo {
|
|||
(error_type(__FUNCTION__ /*src_function*/,
|
||||
"must use \\n or \\r to encode newline/cr in string literal",
|
||||
input_state_,
|
||||
//current_line_,
|
||||
//current_pos_,
|
||||
//whitespace.size(),
|
||||
(ix - tk_start)));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ namespace xo {
|
|||
/** sentinel value **/
|
||||
tk_invalid = -1,
|
||||
|
||||
/** a boolean constant **/
|
||||
tk_bool,
|
||||
|
||||
/** an integer constant (signed 64-bit integer) **/
|
||||
tk_i64,
|
||||
|
||||
|
|
@ -135,6 +138,12 @@ namespace xo {
|
|||
/** keyword @c 'if' **/
|
||||
tk_if,
|
||||
|
||||
/** keyworkd @c 'then' **/
|
||||
tk_then,
|
||||
|
||||
/** keyword @c 'else' **/
|
||||
tk_else,
|
||||
|
||||
/** keyword @c 'let' **/
|
||||
tk_let,
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ namespace xo {
|
|||
#define CASE(x) case tokentype::x: return STRINGIFY(x)
|
||||
|
||||
switch(tk_type) {
|
||||
CASE(tk_bool);
|
||||
CASE(tk_i64);
|
||||
CASE(tk_f64);
|
||||
CASE(tk_string);
|
||||
|
|
@ -46,6 +47,8 @@ namespace xo {
|
|||
CASE(tk_def);
|
||||
CASE(tk_lambda);
|
||||
CASE(tk_if);
|
||||
CASE(tk_then);
|
||||
CASE(tk_else);
|
||||
CASE(tk_let);
|
||||
|
||||
CASE(tk_in);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue