Skip to content

Commit 6c608be

Browse files
committed
Improve detection of procedure declaration mistakes
1 parent 61485f5 commit 6c608be

File tree

1 file changed

+30
-20
lines changed

1 file changed

+30
-20
lines changed

src/parsing/parser.rs

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -283,15 +283,12 @@ impl<'i> Parser<'i> {
283283
.push(error);
284284
}
285285
}
286-
} else if self
287-
.source
288-
.contains(':')
289-
{
286+
} else if potential_procedure_declaration(self.source) {
290287
// It might be that we've encountered a malformed procedure
291288
// declaration, so we try parsing it anyway to get a more
292289
// specific error message.
293290
match self.take_block_lines(
294-
|_| true, // Accept the line regardless
291+
potential_procedure_declaration,
295292
|line| is_section(line) || potential_procedure_declaration(line),
296293
|inner| inner.read_procedure(),
297294
) {
@@ -2580,24 +2577,37 @@ fn is_procedure_declaration(content: &str) -> bool {
25802577
/// reporting what turns out to be a better error.
25812578
fn potential_procedure_declaration(content: &str) -> bool {
25822579
match content.split_once(':') {
2583-
Some((before, _after)) => {
2580+
Some((before, after)) => {
25842581
let before = before.trim_ascii();
2585-
// Check if it looks like an identifier (possibly with parameters)
2586-
// Accept any single token that could be an attempted identifier
2587-
if let Some((name, params)) = before.split_once('(') {
2588-
// Has parameters: check if params end with ')'
2589-
!name
2582+
2583+
// Empty before colon -> only a declaration if there's something after
2584+
if before.is_empty() {
2585+
return !after
25902586
.trim_ascii()
2591-
.is_empty()
2592-
&& params.ends_with(')')
2593-
} else {
2594-
// No parameters: must be a single token (no spaces) that
2595-
// looks identifier-ish This excludes sentences like "Ask
2596-
// these questions: ..."
2597-
!before.is_empty() &&
2598-
!before.contains(' ') && // Single token only
2599-
before.chars().all(|c| c.is_ascii_alphanumeric() || c == '_')
2587+
.is_empty();
26002588
}
2589+
2590+
// Has parentheses -> likely trying to be a procedure with parameters
2591+
if before.contains('(') {
2592+
return true;
2593+
}
2594+
2595+
// Check if it looks like prose vs an identifier attempt
2596+
// Prose typically: starts with capital, has multiple space-separated words
2597+
// Identifiers: lowercase, possibly with underscores
2598+
let first_char = before
2599+
.chars()
2600+
.next()
2601+
.unwrap();
2602+
let has_spaces = before.contains(' ');
2603+
2604+
// If it starts with uppercase AND has spaces, it's probably prose
2605+
if first_char.is_uppercase() && has_spaces {
2606+
return false;
2607+
}
2608+
2609+
// Otherwise, could be a procedure declaration attempt
2610+
true
26012611
}
26022612
None => false,
26032613
}

0 commit comments

Comments
 (0)