Refactor name parsing

This commit is contained in:
imaqtkatt 2024-05-24 11:23:48 -03:00
parent ef25fdb867
commit f92932063b
2 changed files with 18 additions and 20 deletions

View File

@ -46,7 +46,7 @@ def main:
A function definition is composed by a name, a sequence of parameters and a body.
A top-level name can be anything matching the regex `[A-Za-z0-9_.-/]+`, except it can't have `__` (used for generated names).
A top-level name can be anything matching the regex `[A-Za-z0-9_.-/]+`, except it can't have `__` (used for generated names) or start with `//`.
The last statement of each function must either be a `return` or a selection statement (`if`, `switch`, `match`, `fold`)
where all branches `return`.
@ -621,7 +621,7 @@ Name (Ctr1 sub_arg1 sub_arg2) arg3 = rule0_body
Name Ctr2 arg3 = rule1_body
```
A top-level name can be anything matching the regex `[A-Za-z0-9_.-/]+`, except it can't have `__` (used for generated names).
A top-level name can be anything matching the regex `[A-Za-z0-9_.-/]+`, except it can't have `__` (used for generated names) or start with `//`.
### Function Definitions

View File

@ -805,33 +805,31 @@ pub trait ParserCommons<'a>: Parser<'a> {
}
}
fn parse_top_level_name(&mut self) -> ParseResult<Name> {
fn parse_restricted_name(&mut self, kind: &str) -> ParseResult<Name> {
let ini_idx = *self.index();
let nam = self.parse_bend_name()?;
let name = self.take_while(|c| c.is_ascii_alphanumeric() || c == '_' || c == '.' || c == '-' || c == '/');
if name.is_empty() {
self.expected("name")?
}
let name = Name::new(name.to_owned());
let end_idx = *self.index();
if nam.contains("__") {
let msg = "Top-level names are not allowed to contain \"__\".".to_string();
if name.contains("__") {
let msg = format!("{kind} names are not allowed to contain \"__\".");
self.with_ctx(Err(msg), ini_idx, end_idx)
} else if nam.starts_with("//") {
let msg = "Top-level names are not allowed to start with \"//\".".to_string();
} else if name.starts_with("//") {
let msg = format!("{kind} names are not allowed to start with \"//\".");
self.with_ctx(Err(msg), ini_idx, end_idx)
} else {
Ok(nam)
Ok(name)
}
}
fn parse_top_level_name(&mut self) -> ParseResult<Name> {
self.parse_restricted_name("Top-level")
}
fn parse_bend_name(&mut self) -> ParseResult<Name> {
let ini_idx = *self.index();
let name = self.take_while(|c| c.is_ascii_alphanumeric() || c == '_' || c == '.' || c == '-' || c == '/');
let end_idx = *self.index();
if name.contains("__") {
let msg = "Variable names are not allowed to contain \"__\".".to_string();
self.with_ctx(Err(msg), ini_idx, end_idx)
} else if name.is_empty() {
self.expected("name")
} else {
Ok(Name::new(name.to_owned()))
}
self.parse_restricted_name("Variable")
}
/// Consumes exactly the text without skipping.