Improve block body's diagnostics
This commit is contained in:
parent
9d3313995e
commit
b1f0714483
18 changed files with 783 additions and 119 deletions
|
|
@ -16,45 +16,40 @@ use rottlib::parser::Parser;
|
|||
/// Keep these small: the goal is to inspect lexer diagnostics and delimiter
|
||||
/// recovery behavior, not full parser behavior.
|
||||
const TEST_CASES: &[(&str, &str)] = &[
|
||||
// L0001: invalid or unknown token
|
||||
(
|
||||
"files/L0001_01.uc",
|
||||
"`",
|
||||
),
|
||||
|
||||
// L0002: unexpected closing delimiter
|
||||
(
|
||||
"files/L0002_01.uc",
|
||||
"]",
|
||||
),
|
||||
|
||||
// L0003: unclosed delimiter before later closing delimiter
|
||||
// P0027: `else` without a matching `if`
|
||||
//
|
||||
// The `}` can still recover by matching the earlier `{`.
|
||||
// `else` cannot start a standalone block item. The parser should report
|
||||
// P0027 at `else`, then recover by bailing out of the current block.
|
||||
(
|
||||
"files/L0003_01.uc",
|
||||
"{\n foo(\n}\n",
|
||||
"files/P0027_01.uc",
|
||||
"{\n local bool bReady;\n bReady = CheckReady();\n else { StartMatch(); }\n NotifyReady();\n}\n",
|
||||
),
|
||||
|
||||
// L0004: mismatched closing delimiter
|
||||
(
|
||||
"files/L0004_01.uc",
|
||||
"(]",
|
||||
),
|
||||
|
||||
// L0005: unclosed delimiter at end of file
|
||||
(
|
||||
"files/L0005_01.uc",
|
||||
"foo(",
|
||||
),
|
||||
|
||||
// Mixed recovery case:
|
||||
// P0027: `case` outside of a `switch`
|
||||
//
|
||||
// `)` recovers by matching `(` after treating `[` as unclosed;
|
||||
// the following `]` is then unexpected.
|
||||
// `case` is a switch-arm boundary, not a valid statement or expression
|
||||
// starter in an ordinary block.
|
||||
(
|
||||
"files/L_mixed_01.uc",
|
||||
"([)]",
|
||||
"files/P0027_02.uc",
|
||||
"{ local int Count; Count = 3; case 3: Count++; UpdateHud();}",
|
||||
),
|
||||
|
||||
// P0027: standalone `until` without a preceding `do`
|
||||
//
|
||||
// `until` is only meaningful as the tail of `do ... until`, so it should
|
||||
// not be accepted as a normal block item.
|
||||
(
|
||||
"files/P0027_03.uc",
|
||||
"{\n local bool bDone;\n bDone = false;\n until (bDone)\n TickWork();\n}\n",
|
||||
),
|
||||
|
||||
// P0027: preprocessor/exec directive inside a statement block
|
||||
//
|
||||
// `#exec` is declaration/top-level-like syntax, not a valid statement or
|
||||
// expression inside a braced statement block.
|
||||
(
|
||||
"files/P0027_04.uc",
|
||||
"{\n local int Count;\n Count = 0;\n #exec TEXTURE IMPORT NAME=Bad FILE=Bad.bmp\n Count++;\n}\n",
|
||||
),
|
||||
];
|
||||
|
||||
|
|
@ -62,12 +57,12 @@ const TEST_CASES: &[(&str, &str)] = &[
|
|||
///
|
||||
/// For lexer-focused fixtures this is usually noisy, so keep it off unless you
|
||||
/// want to inspect how parser recovery behaves after lexer diagnostics.
|
||||
const RUN_PARSER: bool = false;
|
||||
const RUN_PARSER: bool = true;
|
||||
|
||||
/// If true, print the parsed expression using Debug formatting.
|
||||
const PRINT_PARSED_EXPR: bool = false;
|
||||
|
||||
/// If true, print diagnostics even when parsing returned a value.
|
||||
const PRINT_LEXER_DIAGNOSTICS: bool = false;
|
||||
const ALWAYS_PRINT_DIAGNOSTICS: bool = true;
|
||||
|
||||
fn main() {
|
||||
|
|
@ -89,7 +84,7 @@ fn main() {
|
|||
} else {
|
||||
had_any_problem = true;
|
||||
|
||||
if ALWAYS_PRINT_DIAGNOSTICS {
|
||||
if PRINT_LEXER_DIAGNOSTICS {
|
||||
println!("Lexer diagnostics:");
|
||||
for diag in lexer_diagnostics {
|
||||
render_diagnostic(diag, &tf, Some(label), false);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue