Parse escape sequences in strings

This commit is contained in:
2026-05-31 01:41:39 +02:00
parent 7401038971
commit 9634ad51a2
4 changed files with 253 additions and 166 deletions
+37 -4
View File
@@ -9,6 +9,7 @@ program;
(* - Allow assigning variables refering to aggregates. *)
(* - Cast expressions. *)
(* - Strings are typed as records with a pointer and length. *)
type
ElnaListNode = record
@@ -58,7 +59,7 @@ type
kind: ElnaTypeKind;
size: Word;
alignment: Word;
members: Word;
members: ^ElnaTypeField;
length: Word
end;
ElnaTypePointer = record
@@ -692,6 +693,7 @@ var
word_type: ^ElnaType;
char_type: ^ElnaType;
bool_type: ^ElnaType;
string_type: ^ElnaTypeRecord;
source_code: Word;
compiler_strings_position: Word;
@@ -4934,7 +4936,7 @@ end;
proc elna_type_string_literal(parser_node: ^ElnaTreeStringLiteral);
begin
parser_node^.type_decoration := word_type
parser_node^.type_decoration := string_type
end;
proc elna_type_boolean_literal(parser_node: ^ElnaTreeBooleanLiteral);
@@ -5291,12 +5293,39 @@ begin
symbol_table^.count := symbol_table^.count + 1
end;
proc elna_symbol_string_build();
var
current_field: ^ElnaTypeField;
char_pointer: ^ElnaTypePointer;
begin
string_type := malloc(#size(ElnaTypeRecord));
string_type^.kind := ElnaTypeKind._record;
string_type^.size := 8;
string_type^.alignment := 4;
string_type^.members := malloc(2 * #size(ElnaTypeField));
char_pointer := malloc(#size(ElnaTypePointer));
char_pointer^.kind := ElnaTypeKind.pointer;
char_pointer^.size := 4;
char_pointer^.alignment := 4;
char_pointer^.base := char_type;
current_field := string_type^.members;
current_field^.name := "ptr";
current_field^.length := 3;
current_field^.field_type := char_pointer;
current_field := current_field + 1;
current_field^.name := "length";
current_field^.length := 6;
current_field^.field_type := word_type
end;
(* Build global symbol table with predefined symbols. *)
proc elna_symbol_table_build();
var
current_info: ^ElnaSymbolTypeInfo;
current_type: ^ElnaType;
global_pointer: ^Word;
begin
symbol_table_global := elna_symbol_table_create(nil);
@@ -5327,7 +5356,11 @@ begin
char_type^.size := 1;
char_type^.alignment := 1;
current_info := type_info_create(char_type);
elna_symbol_table_enter(symbol_table_global, "Char", 4, current_info)
elna_symbol_table_enter(symbol_table_global, "Char", 4, current_info);
elna_symbol_string_build();
current_info := type_info_create(string_type);
elna_symbol_table_enter(symbol_table_global, "String", 6, current_info)
end;
proc elna_lexer_classifications1();
+213 -155
View File
@@ -8,6 +8,8 @@ program;
(* Stage 22 compiler. *)
(* - Support 2 word procedure arguments. *)
(* - Characters are parsed to a character ASCII code. *)
(* - Strings are parsed and their length doesn't count for escaping backslash. *)
type
ElnaListNode = record
@@ -138,7 +140,7 @@ type
ElnaTreeStringLiteral = record
kind: ElnaTreeKind;
type_decoration: ^ElnaType;
value: Word;
value: ^Char;
length: Word
end
ElnaTreeVariableExpression = record
@@ -679,14 +681,9 @@ type
var
symbol_table_global: ^ElnaSymbolTable
variable_map_global: ^ElnaSymbolTable
compiler_strings: [1024]Word
compiler_strings: [4096]Char
classification: [256]Word
(**
* Lexer state is saved after the transition tables.
* Each transition table entry is 8 bytes long. The table has 19 rows (transition states)
* and 23 columns (character classes), so 3496 = 8 * 19 * 23.
*)
transition_table: [19][23]ElnaLexerTransition
word_type: ^ElnaType
char_type: ^ElnaType
@@ -705,33 +702,70 @@ var
*
* Parameters:
* string - String token.
* string_length - String length.
*
* Returns the offset from the beginning of the storage to the new string in a0.
* Returns the offset from the beginning of the storage to the new string.
*)
proc _add_string(string: ^Char) -> Word
proc elna_tac_add_string(string: ^Char, string_length: Word) -> Word
var
contents: Word
result: Word
current_byte: Char
length_to_copy: Word
current_target: ^Char
begin
contents := string + 1;
result := compiler_strings_length;
length_to_copy := 0;
(* Global character pointer is appearently dereferenced wrongly. *)
current_target := compiler_strings_position;
.add_string_loop;
current_byte := contents^;
if current_byte <> '"' then
length_to_copy := length_to_copy + 1;
contents := contents + 1;
current_byte := string^;
if current_byte <> '\\' then
compiler_strings_length := compiler_strings_length + 1
if current_byte = 92 then
current_target^ := '\\';
current_target := current_target + 1;
current_target^ := '\\'
elsif current_byte = 10 then
current_target^ := '\\';
current_target := current_target + 1;
current_target^ := 'n'
elsif current_byte = 9 then
current_target^ := '\\';
current_target := current_target + 1;
current_target^ := 't'
elsif current_byte = 12 then
current_target^ := '\\';
current_target := current_target + 1;
current_target^ := 'f'
elsif current_byte = 13 then
current_target^ := '\\';
current_target := current_target + 1;
current_target^ := 'r'
elsif current_byte = 11 then
current_target^ := '\\';
current_target := current_target + 1;
current_target^ := 'v'
elsif current_byte = 34 then
current_target^ := '\\';
current_target := current_target + 1;
current_target^ := '"'
elsif current_byte = 39 then
current_target^ := '\\';
current_target := current_target + 1;
current_target^ := '\''
elsif current_byte = 0 then
current_target^ := '\\';
current_target := current_target + 1;
current_target^ := '0'
else
current_target^ := current_byte
end;
current_target := current_target + 1;
string := string + 1;
string_length := string_length - 1;
compiler_strings_length := compiler_strings_length + 1;
if string_length > 0 then
goto add_string_loop
end;
memcpy(compiler_strings_position, string + 1, length_to_copy);
compiler_strings_position := compiler_strings_position + length_to_copy;
compiler_strings_position := current_target;
return result
end
@@ -756,7 +790,7 @@ end
*)
proc _write_i(number: Word)
begin
printf("%i\0", number);
printf("%i\0".ptr, number);
fflush(nil)
end
@@ -826,7 +860,7 @@ begin
pseudo_counter := pseudo_counter + 1;
buffer := malloc(7);
sprintf(buffer, "$a%i\0", pseudo_counter);
sprintf(buffer, "$a%i\0".ptr, pseudo_counter);
operand^.kind := ElnaTacKind.variable;
operand^.value := buffer;
@@ -1385,7 +1419,7 @@ begin
elna_list_append(instructions, instruction);
instruction := elna_rtl_instruction_create(ElnaRtlOperator.jal);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.data, "memcpy", 6, 0);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.data, "memcpy".ptr, 6, 0);
elna_list_append(instructions, instruction)
end
@@ -1518,91 +1552,91 @@ var
begin
if instruction_kind = ElnaRtlOperator.li then
argument_count := 2;
_write_s("\tli", 3)
_write_s("\tli".ptr, 3)
elsif instruction_kind = ElnaRtlOperator.la then
argument_count := 2;
_write_s("\tla", 3)
_write_s("\tla".ptr, 3)
elsif instruction_kind = ElnaRtlOperator.add then
argument_count := 3;
_write_s("\tadd", 4)
_write_s("\tadd".ptr, 4)
elsif instruction_kind = ElnaRtlOperator.addi then
argument_count := 3;
_write_s("\taddi", 5)
_write_s("\taddi".ptr, 5)
elsif instruction_kind = ElnaRtlOperator.lw then
argument_count := 2;
if source_type^.kind = ElnaRtlTypeKind.byte then
_write_s("\tlb", 3)
_write_s("\tlb".ptr, 3)
else
_write_s("\tlw", 3)
_write_s("\tlw".ptr, 3)
end
elsif instruction_kind = ElnaRtlOperator.sw then
argument_count := 2;
if source_type^.kind = ElnaRtlTypeKind.byte then
_write_s("\tsb", 3)
_write_s("\tsb".ptr, 3)
else
_write_s("\tsw", 3)
_write_s("\tsw".ptr, 3)
end
elsif instruction_kind = ElnaRtlOperator.jal then
argument_count := 1;
_write_s("\tcall", 5)
_write_s("\tcall".ptr, 5)
elsif instruction_kind = ElnaRtlOperator.mv then
argument_count := 2;
_write_s("\tmv", 3)
_write_s("\tmv".ptr, 3)
elsif instruction_kind = ElnaRtlOperator.sub then
argument_count := 3;
_write_s("\tsub", 4)
_write_s("\tsub".ptr, 4)
elsif instruction_kind = ElnaRtlOperator.mul then
argument_count := 3;
_write_s("\tmul", 4)
_write_s("\tmul".ptr, 4)
elsif instruction_kind = ElnaRtlOperator.div then
argument_count := 3;
_write_s("\tdiv", 4)
_write_s("\tdiv".ptr, 4)
elsif instruction_kind = ElnaRtlOperator.rem then
argument_count := 3;
_write_s("\trem", 4)
_write_s("\trem".ptr, 4)
elsif instruction_kind = ElnaRtlOperator._xor then
argument_count := 3;
_write_s("\txor", 4)
_write_s("\txor".ptr, 4)
elsif instruction_kind = ElnaRtlOperator.xori then
argument_count := 3;
_write_s("\txori", 5)
_write_s("\txori".ptr, 5)
elsif instruction_kind = ElnaRtlOperator._or then
argument_count := 3;
_write_s("\tor", 3)
_write_s("\tor".ptr, 3)
elsif instruction_kind = ElnaRtlOperator.and then
argument_count := 3;
_write_s("\tand", 4)
_write_s("\tand".ptr, 4)
elsif instruction_kind = ElnaRtlOperator.seqz then
argument_count := 2;
_write_s("\tseqz", 5)
_write_s("\tseqz".ptr, 5)
elsif instruction_kind = ElnaRtlOperator.snez then
argument_count := 2;
_write_s("\tsnez", 5)
_write_s("\tsnez".ptr, 5)
elsif instruction_kind = ElnaRtlOperator.slt then
argument_count := 3;
_write_s("\tslt", 4)
_write_s("\tslt".ptr, 4)
elsif instruction_kind = ElnaRtlOperator.neg then
argument_count := 2;
_write_s("\tneg", 4)
_write_s("\tneg".ptr, 4)
elsif instruction_kind = ElnaRtlOperator.not then
argument_count := 2;
_write_s("\tnot", 4)
_write_s("\tnot".ptr, 4)
elsif instruction_kind = ElnaRtlOperator.j then
argument_count := 1;
_write_s("\tj", 2)
_write_s("\tj".ptr, 2)
elsif instruction_kind = ElnaRtlOperator.beqz then
argument_count := 2;
_write_s("\tbeqz", 5)
_write_s("\tbeqz".ptr, 5)
elsif instruction_kind = ElnaRtlOperator.bnez then
argument_count := 2;
_write_s("\tbnez", 5)
_write_s("\tbnez".ptr, 5)
end;
return argument_count
end
proc elna_riscv_register(register: Word)
begin
printf("x%i\0", register - 1);
printf("x%i\0".ptr, register - 1);
fflush(nil)
end
@@ -2010,24 +2044,24 @@ begin
operand_value := instruction^.operands[1].value;
(* Write the prologue. *)
printf("\taddi sp, sp, -%i\n\tsw ra, %i(sp)\n\tsw s0, %i(sp)\n\taddi s0, sp, %i\n\0",
printf("\taddi sp, sp, -%i\n\tsw ra, %i(sp)\n\tsw s0, %i(sp)\n\taddi s0, sp, %i\n\0".ptr,
operand_value, operand_value - 4, operand_value - 8, operand_value);
fflush(nil)
elsif instruction^.operator = ElnaRtlOperator.ret then
operand_value := instruction^.operands[1].value;
(* Write the epilogue. *)
printf("\tlw ra, %i(sp)\n\tlw s0, %i(sp)\n\taddi sp, sp, %i\n\0", operand_value - 4, operand_value - 8, operand_value);
printf("\tlw ra, %i(sp)\n\tlw s0, %i(sp)\n\taddi sp, sp, %i\n\0".ptr, operand_value - 4, operand_value - 8, operand_value);
fflush(nil)
elsif instruction^.operator = ElnaRtlOperator.nop then
operand_value := instruction^.operands[1].kind;
if operand_value = ElnaTacKind.constant then
printf("\n# copy %i (%i %i) (%i %.*s)\n\0", instruction^.operands[3].kind,
printf("\n# copy %i (%i %i) (%i %.*s)\n\0".ptr, instruction^.operands[3].kind,
instruction^.operands[1].kind, instruction^.operands[1].value,
instruction^.operands[2].kind, instruction^.operands[2].length, instruction^.operands[2].value)
else
printf("\n# copy (%i %.*s) (%i %.*s)\n\0",
printf("\n# copy (%i %.*s) (%i %.*s)\n\0".ptr,
instruction^.operands[1].kind, instruction^.operands[1].length, instruction^.operands[1].value,
instruction^.operands[2].kind, instruction^.operands[2].length, instruction^.operands[2].value)
end;
@@ -2117,13 +2151,13 @@ begin
.elna_riscv_procedure_loop;
(* Write .type _procedure_name, @function. *)
printf(".type %.*s, @function\n\0", procedure^.length, procedure^.name);
printf(".type %.*s, @function\n\0".ptr, procedure^.length, procedure^.name);
(* Write procedure label, _procedure_name: *)
printf("%.*s:\n\0", procedure^.length, procedure^.name);
printf("%.*s:\n\0".ptr, procedure^.length, procedure^.name);
elna_riscv_instructions(procedure^.body.first);
printf("\tret\n\0");
printf("\tret\n\0".ptr);
fflush(nil);
procedure := procedure^.next;
@@ -2136,9 +2170,9 @@ proc elna_riscv_variable(variable: ^ElnaRtlStaticVariable)
begin
.elna_riscv_variable_loop;
if variable <> 0 then
printf(".type %.*s, @object\n\0", variable^.length, variable^.name);
printf(".type %.*s, @object\n\0".ptr, variable^.length, variable^.name);
printf("%.*s: .zero %i\n\0", variable^.length, variable^.name, variable^.body);
printf("%.*s: .zero %i\n\0".ptr, variable^.length, variable^.name, variable^.body);
variable := variable^.next;
goto elna_riscv_variable_loop
@@ -2241,16 +2275,16 @@ var
compiler_strings_end: ^Char
current_byte: Char
begin
printf(".globl main\n\n\0");
printf(".section .data\n\0");
printf(".globl main\n\n\0".ptr);
printf(".section .data\n\0".ptr);
elna_riscv_variable(pair^.data);
printf(".section .text\n\n\0");
printf(".section .text\n\n\0".ptr);
elna_riscv_procedure(pair^.code);
printf(".section .rodata\n.type strings, @object\nstrings: .ascii \0");
printf(".section .rodata\n.type strings, @object\nstrings: .ascii \0".ptr);
fflush(nil);
_write_c('"');
@@ -2296,7 +2330,7 @@ begin
result := malloc(#size(ElnaTreeBooleanLiteral));
result^.kind := ElnaTreeKind.boolean_literal;
result^.value := string_compare(cursor^.start, 4, "true", 4);
result^.value := string_compare(cursor^.start, 4, "true".ptr, 4);
result^.type_decoration := nil;
elna_lexer_read(cursor);
@@ -2338,6 +2372,55 @@ begin
operand^.length := 4
end
(* Escape a single character if needed. *)
proc elna_parser_escape(current_position: ^Char, result: ^Char) -> Word
var
parsed_length: Word
next_character: Char
begin
next_character := current_position^;
if next_character = '\\' then
parsed_length := 2;
current_position := current_position + 1;
next_character := current_position^;
if next_character = '\\' then
(* \\ Backslash. *)
result^ := 92
elsif next_character = 'n' then
(* \n Newline. *)
result^ := 10
elsif next_character = 't' then
(* \t Tab. *)
result^ := 9
elsif next_character = 'f' then
(* \f Formfeed. *)
result^ := 12
elsif next_character = 'r' then
(* \r Carriage return. *)
result^ := 13
elsif next_character = 'v' then
(* \v Vertical tab. *)
result^ := 11
elsif next_character = '"' then
(* \" Double quote. *)
result^ := 34
elsif next_character = '\'' then
(* \' Single quote. *)
result^ := 39
elsif next_character = '0' then
(* \0 Null character. *)
result^ := 0
end
else
parsed_length := 1;
result^ := next_character
end;
return parsed_length
end
proc elna_parser_character_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeCharacterLiteral
var
result: ^ElnaTreeCharacterLiteral
@@ -2345,10 +2428,11 @@ var
begin
result := malloc(#size(ElnaTreeCharacterLiteral));
token := elna_lexer_read(cursor);
result^.kind := ElnaTreeKind.character_literal;
result^.value := token^.start;
result^.length := token^.length;
elna_parser_escape(token^.start + 1, @result^.value);
result^.length := 0;
result^.type_decoration := nil;
return result
@@ -2360,51 +2444,7 @@ var
current_position: ^Char
begin
operand^.kind := ElnaTacKind.constant;
current_position := character_literal_node^.value + 1;
next_character := current_position^;
(* Escape. *)
if next_character = '\\' then
current_position := current_position + 1;
next_character := current_position^;
if next_character = '\\' then
(* \\ Backslash. *)
operand^.value := 92
elsif next_character = 'n' then
(* \n Newline. *)
operand^.value := 10
elsif next_character = 'a' then
(* \a Bell. *)
operand^.value := 7
elsif next_character = 'b' then
(* \b Backspace. *)
operand^.value := 8
elsif next_character = 't' then
(* \t Tab. *)
operand^.value := 9
elsif next_character = 'f' then
(* \f Formfeed. *)
operand^.value := 12
elsif next_character = 'r' then
(* \r Carriage return. *)
operand^.value := 13
elsif next_character = 'v' then
(* \v Vertical tab. *)
operand^.value := 11
elsif next_character = '"' then
(* \" Double quote. *)
operand^.value := 34
elsif next_character = '\'' then
(* \" Single quote. *)
operand^.value := 39
elsif next_character = '0' then
(* \0 Null character. *)
operand^.value := 0
end
else
operand^.value := next_character
end;
operand^.value := character_literal_node^.value;
operand^.length := 1
end
@@ -2435,13 +2475,31 @@ proc elna_parser_string_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeStringLite
var
result: ^ElnaTreeStringLiteral
token: ^ElnaLexerToken
current_position: ^Char
parsed_length: Word
parsed_total: Word
target_position: ^Char
begin
result := malloc(#size(ElnaTreeStringLiteral));
token := elna_lexer_read(cursor);
target_position := malloc(token^.length - 2);
current_position := token^.start + 1;
parsed_total := 2;
result^.kind := ElnaTreeKind.string_literal;
result^.value := token^.start;
result^.length := token^.length;
result^.value := target_position;
result^.length := 0;
.elna_parser_escape_loop;
parsed_length := elna_parser_escape(current_position, target_position);
current_position := current_position + parsed_length;
parsed_total := parsed_total + parsed_length;
target_position := target_position + 1;
if parsed_total < token^.length then
goto elna_parser_escape_loop
end;
result^.length := target_position - result^.value;
result^.type_decoration := nil;
return result
@@ -2453,12 +2511,12 @@ var
offset: Word
instruction: ^ElnaTacInstruction
begin
offset := _add_string(string_literal_node^.value);
offset := elna_tac_add_string(string_literal_node^.value, string_literal_node^.length);
elna_tac_make_variable(operand, symbol_table, word_type);
instruction := elna_tac_instruction_create(ElnaTacOperator.get_address);
elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.variable, "strings", 7);
elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.variable, "strings".ptr, 7);
elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length);
elna_list_append(instructions, instruction);
@@ -3385,9 +3443,9 @@ var
first_byte: Word
begin
if length = 0 then
printf(".L%i\0", counter)
printf(".L%i\0".ptr, counter)
else
printf(".%.*s\0", length, counter);
printf(".%.*s\0".ptr, length, counter);
end;
fflush(nil)
end
@@ -4207,7 +4265,7 @@ begin
pseudo_symbol^.kind := ElnaRtlInfoKind.object_info;
buffer := malloc(7);
sprintf(buffer, "$b%i\0", pseudo_counter);
sprintf(buffer, "$b%i\0".ptr, pseudo_counter);
pseudo_symbol^.allocated := false;
operand^.value := buffer;
@@ -4683,10 +4741,10 @@ begin
elna_list_initialize(@result^.body);
result^.name := "main";
result^.name := "main".ptr;
result^.length := 4;
symbol_info := elna_symbol_table_lookup(symbol_table_global, "main", 4);
symbol_info := elna_symbol_table_lookup(symbol_table_global, result^.name, result^.length);
result^.symbol_table := symbol_info^.symbol_table;
@@ -4896,7 +4954,7 @@ begin
new_symbol_table := elna_symbol_table_create(symbol_table_global);
symbol_info := procedure_info_create(new_symbol_table);
elna_symbol_table_enter(symbol_table_global, "main", 4, symbol_info)
elna_symbol_table_enter(symbol_table_global, "main".ptr, 4, symbol_info)
end
proc elna_type_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, symbol_table: ^ElnaSymbolTable)
@@ -4993,7 +5051,7 @@ end
proc elna_type_string_literal(parser_node: ^ElnaTreeStringLiteral)
begin
parser_node^.type_decoration := word_type
parser_node^.type_decoration := string_type
end
proc elna_type_boolean_literal(parser_node: ^ElnaTreeBooleanLiteral)
@@ -5005,7 +5063,7 @@ proc elna_type_nil_literal(parser_node: ^ElnaTreeNilLiteral)
var
symbol_info: ^ElnaSymbolTypeInfo
begin
symbol_info := elna_symbol_table_lookup(symbol_table_global, "Pointer", 7);
symbol_info := elna_symbol_table_lookup(symbol_table_global, "Pointer".ptr, 7);
parser_node^.type_decoration := symbol_info^._type
end
@@ -5368,14 +5426,14 @@ begin
char_pointer^.base := char_type;
current_field := string_type^.members;
current_field^.name := "ptr";
current_field^.name := "ptr".ptr;
current_field^.length := 3;
current_field^.field_type := char_pointer;
current_field := current_field + 1;
current_field^.name := "length";
current_field^.name := "length".ptr;
current_field^.length := 6;
current_field^.field_type := word_type;
current_field^.field_type := word_type
end
(* Build global symbol table with predefined symbols. *)
@@ -5391,32 +5449,32 @@ begin
word_type^.size := 4;
word_type^.alignment := 4;
current_info := type_info_create(word_type);
elna_symbol_table_enter(symbol_table_global, "Word", 4, current_info);
elna_symbol_table_enter(symbol_table_global, "Word".ptr, 4, current_info);
current_type := malloc(#size(ElnaType));
current_type^.kind := ElnaTypeKind.primitive;
current_type^.size := 4;
current_type^.alignment := 4;
current_info := type_info_create(current_type);
elna_symbol_table_enter(symbol_table_global, "Pointer", 7, current_info);
elna_symbol_table_enter(symbol_table_global, "Pointer".ptr, 7, current_info);
bool_type := malloc(#size(ElnaType));
bool_type^.kind := ElnaTypeKind.primitive;
bool_type^.size := 1;
bool_type^.alignment := 1;
current_info := type_info_create(bool_type);
elna_symbol_table_enter(symbol_table_global, "Bool", 4, current_info);
elna_symbol_table_enter(symbol_table_global, "Bool".ptr, 4, current_info);
char_type := malloc(#size(ElnaType));
char_type^.kind := ElnaTypeKind.primitive;
char_type^.size := 1;
char_type^.alignment := 1;
current_info := type_info_create(char_type);
elna_symbol_table_enter(symbol_table_global, "Char", 4, current_info);
elna_symbol_table_enter(symbol_table_global, "Char".ptr, 4, current_info);
elna_symbol_string_build();
current_info := type_info_create(string_type);
elna_symbol_table_enter(symbol_table_global, "String", 6, current_info)
elna_symbol_table_enter(symbol_table_global, "String".ptr, 6, current_info)
end
proc elna_lexer_classifications1()
@@ -5820,49 +5878,49 @@ begin
if position_start^ = '#' then
result^.kind := ElnaLexerKind.trait
elsif string_compare(position_start, result^.length, "const", 5) then
elsif string_compare(position_start, result^.length, "const".ptr, 5) then
result^.kind := ElnaLexerKind._const
elsif string_compare(position_start, result^.length, "var", 3) then
elsif string_compare(position_start, result^.length, "var".ptr, 3) then
result^.kind := ElnaLexerKind._var
elsif string_compare(position_start, result^.length, "proc", 4) then
elsif string_compare(position_start, result^.length, "proc".ptr, 4) then
result^.kind := ElnaLexerKind._proc
elsif string_compare(position_start, result^.length, "type", 4) then
elsif string_compare(position_start, result^.length, "type".ptr, 4) then
result^.kind := ElnaLexerKind._type
elsif string_compare(position_start, result^.length, "begin", 5) then
elsif string_compare(position_start, result^.length, "begin".ptr, 5) then
result^.kind := ElnaLexerKind._begin
elsif string_compare(position_start, result^.length, "end", 3) then
elsif string_compare(position_start, result^.length, "end".ptr, 3) then
result^.kind := ElnaLexerKind._end
elsif string_compare(position_start, result^.length, "return", 6) then
elsif string_compare(position_start, result^.length, "return".ptr, 6) then
result^.kind := ElnaLexerKind._return
elsif string_compare(position_start, result^.length, "goto", 4) then
elsif string_compare(position_start, result^.length, "goto".ptr, 4) then
result^.kind := ElnaLexerKind._goto
elsif string_compare(position_start, result^.length, "if", 2) then
elsif string_compare(position_start, result^.length, "if".ptr, 2) then
result^.kind := ElnaLexerKind._if
elsif string_compare(position_start, result^.length, "while", 5) then
elsif string_compare(position_start, result^.length, "while".ptr, 5) then
result^.kind := ElnaLexerKind._while
elsif string_compare(position_start, result^.length, "then", 4) then
elsif string_compare(position_start, result^.length, "then".ptr, 4) then
result^.kind := ElnaLexerKind._then
elsif string_compare(position_start, result^.length, "else", 4) then
elsif string_compare(position_start, result^.length, "else".ptr, 4) then
result^.kind := ElnaLexerKind._else
elsif string_compare(position_start, result^.length, "elsif", 5) then
elsif string_compare(position_start, result^.length, "elsif".ptr, 5) then
result^.kind := ElnaLexerKind._elsif
elsif string_compare(position_start, result^.length, "record", 6) then
elsif string_compare(position_start, result^.length, "record".ptr, 6) then
result^.kind := ElnaLexerKind._record
elsif string_compare(position_start, result^.length, "or", 2) then
elsif string_compare(position_start, result^.length, "or".ptr, 2) then
result^.kind := ElnaLexerKind._or
elsif string_compare(position_start, result^.length, "xor", 3) then
elsif string_compare(position_start, result^.length, "xor".ptr, 3) then
result^.kind := ElnaLexerKind._xor
elsif string_compare(position_start, result^.length, "program", 7) then
elsif string_compare(position_start, result^.length, "program".ptr, 7) then
result^.kind := ElnaLexerKind._program
elsif string_compare(position_start, result^.length, "module", 6) then
elsif string_compare(position_start, result^.length, "module".ptr, 6) then
result^.kind := ElnaLexerKind._module
elsif string_compare(position_start, result^.length, "nil", 3) then
elsif string_compare(position_start, result^.length, "nil".ptr, 3) then
result^.kind := ElnaLexerKind.null
elsif string_compare(position_start, result^.length, "true", 4) then
elsif string_compare(position_start, result^.length, "true".ptr, 4) then
result^.kind := ElnaLexerKind.boolean
elsif string_compare(position_start, result^.length, "false", 5) then
elsif string_compare(position_start, result^.length, "false".ptr, 5) then
result^.kind := ElnaLexerKind.boolean
elsif string_compare(position_start, result^.length, "cast", 4) then
elsif string_compare(position_start, result^.length, "cast".ptr, 4) then
result^.kind := ElnaLexerKind._cast
end;
return result
+1 -1
View File
@@ -17,7 +17,7 @@
<hex-character> = `\\x' <hex-digit> \{<hex-digit>\}.
<escaped-character> = `\\' \\
(`n' | `a' | `b' | `t' | `f' | `r' | `v' | `\\' | `\textquotesingle' | `\textquotedbl' | `0').
(`n' | `t' | `f' | `r' | `v' | `\\' | `\textquotesingle' | `\textquotedbl' | `0').
<printable-character> = \enspace? a printable ASCII character\space?.
+1 -5
View File
@@ -84,7 +84,7 @@ called the \textit{the length} of the string.
\begin{grammar}
<escaped-character> = `\\' \\
(`n' | `a' | `b' | `t' | `f' | `r' | `v' | `\\' | `\textquotesingle' | `\textquotedbl' | `0').
(`n' | `t' | `f' | `r' | `v' | `\\' | `\textquotesingle' | `\textquotedbl' | `0').
<hex-character> = `\\x' <hex-digit> \{<hex-digit>\}.
@@ -106,10 +106,6 @@ beginning with a backslash (\textbackslash).
\toprule
\verb|\n| & Newline \\
\midrule
\verb|\a| & Bell \\
\midrule
\verb|\b| & Backspace \\
\midrule
\verb|\t| & Horizontal tab \\
\midrule
\verb|\f| & Form feed \\