From dfb5fb7ef4865aab85415a58bda19d64c38dd117 Mon Sep 17 00:00:00 2001 From: Nikita Strygin Date: Fri, 1 Sep 2023 15:18:47 +0300 Subject: [PATCH] shin-asm: fix parsing of instruction block and instruction args - stop parsing instruction list when expr can no longer be parsed - allow labels only at the start of the instruction block --- .../src/parser/grammar/items/instructions.rs | 22 +++-- shin-asm/test_data/parser/err/0001_junk.sast | 94 +++++++++++++++++++ .../test_data/parser/ok/0016_label_split.sal | 15 +-- .../test_data/parser/ok/0016_label_split.sast | 20 ++++ 4 files changed, 130 insertions(+), 21 deletions(-) create mode 100644 shin-asm/test_data/parser/err/0001_junk.sast create mode 100644 shin-asm/test_data/parser/ok/0016_label_split.sast diff --git a/shin-asm/src/parser/grammar/items/instructions.rs b/shin-asm/src/parser/grammar/items/instructions.rs index 4f980ea..a1556ac 100644 --- a/shin-asm/src/parser/grammar/items/instructions.rs +++ b/shin-asm/src/parser/grammar/items/instructions.rs @@ -3,7 +3,11 @@ use super::*; pub(super) fn instructions_block(p: &mut Parser<'_>) { let m = p.start(); - while p.at(IDENT) { + if p.at(IDENT) { + instruction_or_label(p); + } + + while p.at(IDENT) && !p.nth_at(1, T![:]) { instruction_or_label(p); } @@ -51,15 +55,13 @@ fn instruction(p: &mut Parser<'_>) { fn instr_arg_list(p: &mut Parser<'_>) { let m = p.start(); - while !p.at_ts(EOL_SET) { - delimited( - p, - EOL_SET, - T![,], - expressions::EXPR_FIRST, - |p: &mut Parser<'_>| expressions::expr(p).is_some(), - ); - } + delimited( + p, + EOL_SET, + T![,], + expressions::EXPR_FIRST, + |p: &mut Parser<'_>| expressions::expr(p).is_some(), + ); m.complete(p, INSTR_ARG_LIST); } diff --git a/shin-asm/test_data/parser/err/0001_junk.sast b/shin-asm/test_data/parser/err/0001_junk.sast new file mode 100644 index 0000000..867911c --- /dev/null +++ b/shin-asm/test_data/parser/err/0001_junk.sast @@ -0,0 +1,94 @@ +SOURCE_FILE + WHITESPACE " " + INSTRUCTIONS_BLOCK + LABEL + IDENT "choice_set_base" + COLON ":" + WHITESPACE " " + INSTRUCTION + INSTRUCTION_NAME + IDENT "u16" + ERROR + COMMA "," + NEWLINE "\n" + WHITESPACE " " + LABEL + IDENT "choice_index" + COLON ":" + WHITESPACE " " + INSTRUCTION + INSTRUCTION_NAME + IDENT "u16" + ERROR + COMMA "," + NEWLINE "\n" + WHITESPACE " " + ERROR + ERROR "#" + ERROR + L_BRACK "[" + INSTRUCTIONS_BLOCK + INSTRUCTION + INSTRUCTION_NAME + IDENT "cmd" + INSTR_ARG_LIST + PAREN_EXPR + L_PAREN "(" + NAME_REF_EXPR + IDENT "dest" + R_PAREN ")" + ERROR + R_BRACK "]" + NEWLINE "\n" + WHITESPACE " " + LABEL + IDENT "dest" + COLON ":" + WHITESPACE " " + INSTRUCTION + INSTRUCTION_NAME + IDENT "MemoryAddress" + ERROR + COMMA "," + NEWLINE "\n" + WHITESPACE " " + LABEL + IDENT "choice_visibility_mask" + COLON ":" + WHITESPACE " " + INSTRUCTION + INSTRUCTION_NAME + IDENT "NumberSpec" + ERROR + COMMA "," + NEWLINE "\n" + WHITESPACE " " + LABEL + IDENT "choice_title" + COLON ":" + WHITESPACE " " + INSTRUCTION + INSTRUCTION_NAME + IDENT "U16String" + ERROR + COMMA "," + NEWLINE "\n" + WHITESPACE " " + LABEL + IDENT "variants" + COLON ":" + WHITESPACE " " + INSTRUCTION + INSTRUCTION_NAME + IDENT "StringArray" + ERROR + COMMA "," +error 28: expected a newline +error 55: expected a newline +error 65: expected an instruction or label +error 66: expected an instruction or label +error 76: expected a newline +error 105: expected a newline +error 149: expected a newline +error 182: expected a newline +error 213: expected a newline diff --git a/shin-asm/test_data/parser/ok/0016_label_split.sal b/shin-asm/test_data/parser/ok/0016_label_split.sal index 8b4ff0a..b00f001 100644 --- a/shin-asm/test_data/parser/ok/0016_label_split.sal +++ b/shin-asm/test_data/parser/ok/0016_label_split.sal @@ -1,11 +1,4 @@ -LABEL_2: - add $1, -1, 14 - jt $v0, { - 0 => SNR_0, - 1 => SNR_1, - } -LABEL_3: - SELECT 1, 2, $choice, 14, "NCSELECT", [ - "To Be", - "Not to Be", - ] \ No newline at end of file +BLOCK_1: + hello +BLOCK_2: + world \ No newline at end of file diff --git a/shin-asm/test_data/parser/ok/0016_label_split.sast b/shin-asm/test_data/parser/ok/0016_label_split.sast new file mode 100644 index 0000000..8a1edf6 --- /dev/null +++ b/shin-asm/test_data/parser/ok/0016_label_split.sast @@ -0,0 +1,20 @@ +SOURCE_FILE + INSTRUCTIONS_BLOCK + LABEL + IDENT "BLOCK_1" + COLON ":" + NEWLINE "\n" + WHITESPACE " " + INSTRUCTION + INSTRUCTION_NAME + IDENT "hello" + NEWLINE "\n" + INSTRUCTIONS_BLOCK + LABEL + IDENT "BLOCK_2" + COLON ":" + NEWLINE "\n" + WHITESPACE " " + INSTRUCTION + INSTRUCTION_NAME + IDENT "world"