diff --git a/boot/driver.cc b/boot/driver.cc index 2443dbc..c9a8e58 100644 --- a/boot/driver.cc +++ b/boot/driver.cc @@ -117,7 +117,7 @@ namespace elna::boot } ++current_position; } - result.pop_back(); + result.pop_back(); // Remove the terminating quote character. return result; } diff --git a/boot/lexer.ll b/boot/lexer.ll index 5ac68ff..bed3254 100644 --- a/boot/lexer.ll +++ b/boot/lexer.ll @@ -32,248 +32,289 @@ along with GCC; see the file COPYING3. If not see %x IN_COMMENT +ID1 [A-Za-z_] +ID2 [A-Za-z0-9_] +HIGIT [0-9a-fA-F] +BIGIT [01] + %% %{ this->location.step(); %} { -\*\) BEGIN(INITIAL); -[^*\n]+ ; /* Eat comment in chunks. */ -\* ; /* Eat the lone star. */ -\n+ { - this->location.lines(yyleng); - this->location.step(); - } + \*\) BEGIN(INITIAL); + [^*\n]+ ; /* Eat comment in chunks. */ + \* ; /* Eat the lone star. */ + \n+ { + this->location.lines(yyleng); + this->location.step(); + } } -\(\* BEGIN(IN_COMMENT); -[ \t\r] { - this->location.step(); +\(\* BEGIN(IN_COMMENT); +[ \t\r] { + this->location.step(); +} +\n+ { + this->location.lines(yyleng); +} +if { + return yy::parser::make_IF(this->location); +} +then { + return yy::parser::make_THEN(this->location); +} +else { + return yy::parser::make_ELSE(this->location); +} +elsif { + return yy::parser::make_ELSIF(this->location); +} +while { + return yy::parser::make_WHILE(this->location); +} +do { + return yy::parser::make_DO(this->location); +} +proc { + return yy::parser::make_PROCEDURE(this->location); +} +begin { + return yy::parser::make_BEGIN_BLOCK(this->location); } -\n+ { - this->location.lines(yyleng); - } -if { - return yy::parser::make_IF(this->location); - } -then { - return yy::parser::make_THEN(this->location); - } -else { - return yy::parser::make_ELSE(this->location); - } -elsif { - return yy::parser::make_ELSIF(this->location); - } -while { - return yy::parser::make_WHILE(this->location); - } -do { - return yy::parser::make_DO(this->location); - } -proc { - return yy::parser::make_PROCEDURE(this->location); - } -begin { - return yy::parser::make_BEGIN_BLOCK(this->location); - } -end { - return yy::parser::make_END_BLOCK(this->location); - } -extern { - return yy::parser::make_EXTERN(this->location); - } -const { - return yy::parser::make_CONST(this->location); - } -var { - return yy::parser::make_VAR(this->location); - } -type { - return yy::parser::make_TYPE(this->location); - } -record { - return yy::parser::make_RECORD(this->location); - } -union { - return yy::parser::make_UNION(this->location); - } -true { - return yy::parser::make_BOOLEAN(true, this->location); - } -false { - return yy::parser::make_BOOLEAN(false, this->location); - } -nil { - return yy::parser::make_NIL(this->location); - } -\& { - return yy::parser::make_AND(this->location); - } -xor { - return yy::parser::make_XOR(this->location); - } -or { - return yy::parser::make_OR(this->location); - } -\| { - return yy::parser::make_PIPE(this->location); - } -\~ { - return yy::parser::make_NOT(this->location); - } -return { - return yy::parser::make_RETURN(this->location); - } -module { - return yy::parser::make_MODULE(this->location); - } -program { - return yy::parser::make_PROGRAM(this->location); - } -import { - return yy::parser::make_IMPORT(this->location); - } -cast { - return yy::parser::make_CAST(this->location); - } -defer { - return yy::parser::make_DEFER(this->location); - } -case { - return yy::parser::make_CASE(this->location); - } -of { - return yy::parser::make_OF(this->location); - } -[A-Za-z_][A-Za-z0-9_]* { - return yy::parser::make_IDENTIFIER(yytext, this->location); - } -#[A-Za-z_][A-Za-z0-9_]* { - return yy::parser::make_TRAIT(yytext + 1, this->location); - } -[0-9]+u { - return yy::parser::make_WORD(strtoul(yytext, NULL, 10), this->location); - } -[0-9]+ { - return yy::parser::make_INTEGER(strtol(yytext, NULL, 10), this->location); - } -[0-9]+\.[0-9] { - return yy::parser::make_FLOAT(strtof(yytext, NULL), this->location); - } -'[[:print:]]' { - if (yytext[1] == '\\' || yytext[1] == '\'') - { - REJECT; - } - else - { - return yy::parser::make_CHARACTER(std::string(yytext, 1, 1), this->location); - } - } -'\\x[0-9a-fA-F]{1,2}' { - char character = static_cast(std::stoi(yytext + 3, nullptr, 16)); +end { + return yy::parser::make_END_BLOCK(this->location); +} +extern { + return yy::parser::make_EXTERN(this->location); +} +const { + return yy::parser::make_CONST(this->location); +} +var { + return yy::parser::make_VAR(this->location); +} +type { + return yy::parser::make_TYPE(this->location); +} +record { + return yy::parser::make_RECORD(this->location); +} +union { + return yy::parser::make_UNION(this->location); +} +true { + return yy::parser::make_BOOLEAN(true, this->location); +} +false { + return yy::parser::make_BOOLEAN(false, this->location); +} +nil { + return yy::parser::make_NIL(this->location); +} +\& { + return yy::parser::make_AND(this->location); +} +xor { + return yy::parser::make_XOR(this->location); +} +or { + return yy::parser::make_OR(this->location); +} +\| { + return yy::parser::make_PIPE(this->location); +} +\~ { + return yy::parser::make_NOT(this->location); +} +return { + return yy::parser::make_RETURN(this->location); +} +module { + return yy::parser::make_MODULE(this->location); +} +program { + return yy::parser::make_PROGRAM(this->location); +} +import { + return yy::parser::make_IMPORT(this->location); +} +cast { + return yy::parser::make_CAST(this->location); +} +defer { + return yy::parser::make_DEFER(this->location); +} +case { + return yy::parser::make_CASE(this->location); +} +of { + return yy::parser::make_OF(this->location); +} +{ID1}{ID2}* { + return yy::parser::make_IDENTIFIER(yytext, this->location); +} +#{ID1}{ID2}* { + return yy::parser::make_TRAIT(yytext + 1, this->location); +} +[[:digit:]]+u { + unsigned long result = strtoul(yytext, NULL, 10); - return yy::parser::make_CHARACTER(std::string(&character, 1), this->location); - } -'\\[0nabtfrv\\'"?]' { - char escape = escape_char(yytext[2]); - if (escape == escape_invalid_char) - { - REJECT; - } - return yy::parser::make_CHARACTER(std::string(&escape, 1), this->location); - } -\"[[:print:]]*\" { - std::optional result = escape_string(yytext); - if (!result.has_value()) - { - REJECT; - } - return yy::parser::make_STRING(result.value(), this->location); - } -\( { - return yy::parser::make_LEFT_PAREN(this->location); - } -\) { - return yy::parser::make_RIGHT_PAREN(this->location); - } -\[ { - return yy::parser::make_LEFT_SQUARE(this->location); - } -\] { - return yy::parser::make_RIGHT_SQUARE(this->location); - } -\<\< { - return yy::parser::make_SHIFT_LEFT(this->location); - } -\>\> { - return yy::parser::make_SHIFT_RIGHT(this->location); - } -\>= { - return yy::parser::make_GREATER_EQUAL(this->location); - } -\<= { - return yy::parser::make_LESS_EQUAL(this->location); - } -\> { - return yy::parser::make_GREATER_THAN(this->location); - } -\< { - return yy::parser::make_LESS_THAN(this->location); - } -\<\> { - return yy::parser::make_NOT_EQUAL(this->location); - } -= { - return yy::parser::make_EQUALS(this->location); - } -; { - return yy::parser::make_SEMICOLON(this->location); - } -\. { - return yy::parser::make_DOT(this->location); - } -, { - return yy::parser::make_COMMA(this->location); - } -\+ { - return yy::parser::make_PLUS(this->location); - } -\-> { - return yy::parser::make_ARROW(this->location); - } -\- { - return yy::parser::make_MINUS(this->location); - } -\* { - return yy::parser::make_MULTIPLICATION(this->location); - } -\/ { - return yy::parser::make_DIVISION(this->location); - } -% { - return yy::parser::make_REMAINDER(this->location); - } -:= { - return yy::parser::make_ASSIGNMENT(this->location); - } -: { - return yy::parser::make_COLON(this->location); - } -\^ { - return yy::parser::make_HAT(this->location); - } -@ { - return yy::parser::make_AT(this->location); - } -! { - return yy::parser::make_EXCLAMATION(this->location); - } -. { - std::stringstream ss; + if (errno == ERANGE) + { + REJECT; + } + else + { + return yy::parser::make_WORD(result, this->location); + } +} +[[:digit:]]+ { + long result = strtol(yytext, NULL, 10); - ss << "Illegal character 0x" << std::hex << static_cast(yytext[0]); - driver.add_error(ss.str(), driver.input_file, this->location); - } + if (errno == ERANGE) + { + REJECT; + } + else + { + return yy::parser::make_INTEGER(result, this->location); + } +} +0x{HIGIT}+ { + unsigned long result = strtoul(yytext, NULL, 16); + + if (errno == ERANGE) + { + REJECT; + } + else + { + return yy::parser::make_WORD(result, this->location); + } +} +0b{BIGIT}+ { + unsigned long result = strtoul(yytext, NULL, 2); + + if (errno == ERANGE) + { + REJECT; + } + else + { + return yy::parser::make_WORD(result, this->location); + } +} +[[:digit:]]+\.[[:digit:]]+ { + float result = strtof(yytext, NULL); + + if (errno == ERANGE) + { + REJECT; + } + else + { + return yy::parser::make_FLOAT(result, this->location); + } +} +'[[:print:]]+' { + std::optional result = escape_string(yytext); + if (!result.has_value() || result.value().size() != 1) + { + REJECT; + } + return yy::parser::make_CHARACTER(result.value(), this->location); +} +\"[[:print:]]*\" { + std::optional result = escape_string(yytext); + if (!result.has_value()) + { + REJECT; + } + return yy::parser::make_STRING(result.value(), this->location); +} +\( { + return yy::parser::make_LEFT_PAREN(this->location); +} +\) { + return yy::parser::make_RIGHT_PAREN(this->location); +} +\[ { + return yy::parser::make_LEFT_SQUARE(this->location); +} +\] { + return yy::parser::make_RIGHT_SQUARE(this->location); +} +\<\< { + return yy::parser::make_SHIFT_LEFT(this->location); +} +\>\> { + return yy::parser::make_SHIFT_RIGHT(this->location); +} +\>= { + return yy::parser::make_GREATER_EQUAL(this->location); +} +\<= { + return yy::parser::make_LESS_EQUAL(this->location); +} +\> { + return yy::parser::make_GREATER_THAN(this->location); +} +\< { + return yy::parser::make_LESS_THAN(this->location); +} +\<\> { + return yy::parser::make_NOT_EQUAL(this->location); +} += { + return yy::parser::make_EQUALS(this->location); +} +; { + return yy::parser::make_SEMICOLON(this->location); +} +\. { + return yy::parser::make_DOT(this->location); +} +, { + return yy::parser::make_COMMA(this->location); +} +\+ { + return yy::parser::make_PLUS(this->location); +} +\-> { + return yy::parser::make_ARROW(this->location); +} +\- { + return yy::parser::make_MINUS(this->location); +} +\* { + return yy::parser::make_MULTIPLICATION(this->location); +} +\/ { + return yy::parser::make_DIVISION(this->location); +} +% { + return yy::parser::make_REMAINDER(this->location); +} +:= { + return yy::parser::make_ASSIGNMENT(this->location); +} +: { + return yy::parser::make_COLON(this->location); +} +\^ { + return yy::parser::make_HAT(this->location); +} +@ { + return yy::parser::make_AT(this->location); +} +! { + return yy::parser::make_EXCLAMATION(this->location); +} +. { + std::stringstream ss; + + ss << "Illegal character 0x" << std::hex << static_cast(yytext[0]); + driver.add_error(ss.str(), driver.input_file, this->location); +} %% diff --git a/source/main.elna b/source/main.elna index 0f3d001..2da63e7 100644 --- a/source/main.elna +++ b/source/main.elna @@ -1074,6 +1074,12 @@ begin return return_code end; +proc f(); +var x: Char; +begin + x := '\x4' +end; + begin exit(process(count, parameters)) end.