Skip to content

Commit f6268c5

Browse files
authored
Validate identifier (#465)
Validate basic identifiers and refactor diagnostic handling for error tolerant parsing
1 parent 0cf5980 commit f6268c5

3 files changed

Lines changed: 350 additions & 162 deletions

File tree

vhdl_lang/src/syntax/test.rs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,9 @@ impl Code {
333333
&self.pos.source
334334
}
335335

336-
fn tokenize_result_raw(&self) -> (Vec<Result<Token, Diagnostic>>, Vec<Comment>, usize) {
336+
fn tokenize_result_raw(&self) -> (Vec<Token>, Vec<Diagnostic>, Vec<Comment>, usize) {
337337
let mut tokens = Vec::new();
338+
let mut diagnostics = Vec::new();
338339
let final_comments: Vec<Comment>;
339340
let mut dropped_tokens: usize = 0;
340341
{
@@ -347,42 +348,47 @@ impl Code {
347348
let reader = ContentReader::new(&contents);
348349
let mut tokenizer = Tokenizer::new(&self.symbols, &source, reader);
349350
loop {
350-
let token = tokenizer.pop();
351-
352-
match token {
351+
match tokenizer.pop() {
353352
Ok(None) => break,
354353
Ok(Some(token)) => {
355354
if token.pos.start() >= self.pos.start() {
356-
tokens.push(Ok(token));
355+
tokens.push(token);
357356
} else {
358357
dropped_tokens += 1;
359358
}
360359
}
361-
Err(err) => tokens.push(Err(err)),
360+
Err(err) => diagnostics.push(err),
362361
}
363362
}
363+
diagnostics.extend(tokenizer.take_diagnostics());
364364
match tokenizer.get_final_comments() {
365365
Some(comments) => final_comments = comments,
366366
None => panic!("Tokenizer failed to check for final comments."),
367367
}
368368
}
369-
(tokens, final_comments, dropped_tokens)
369+
(tokens, diagnostics, final_comments, dropped_tokens)
370370
}
371371

372-
/// Helper method to test tokenization functions
373-
pub fn tokenize_result(&self) -> (Vec<Result<Token, Diagnostic>>, Vec<Comment>) {
374-
let (tokens, final_comments, _) = self.tokenize_result_raw();
375-
(tokens, final_comments)
372+
/// Helper method to test tokenization functions. Returns the produced
373+
/// tokens, any diagnostics emitted during tokenization, and final
374+
/// (file-level) comments.
375+
pub fn tokenize_result(&self) -> (Vec<Token>, Vec<Diagnostic>, Vec<Comment>) {
376+
let (tokens, diagnostics, final_comments, _) = self.tokenize_result_raw();
377+
(tokens, diagnostics, final_comments)
376378
}
377379

378380
/// Tokenize and check that there are no errors, ignore final comments
379381
pub fn tokenize(&self) -> Vec<Token> {
380-
let tokens = self.tokenize_result().0;
381-
tokens.into_iter().map(|tok| tok.unwrap()).collect()
382+
let (tokens, diagnostics, _) = self.tokenize_result();
383+
assert!(
384+
diagnostics.is_empty(),
385+
"expected no tokenizer diagnostics, got {diagnostics:?}",
386+
);
387+
tokens
382388
}
383389

384390
pub fn token_span(&self) -> TokenSpan {
385-
let (tokens, _, dropped_tokens) = self.tokenize_result_raw();
391+
let (tokens, _, _, dropped_tokens) = self.tokenize_result_raw();
386392
let start_token = TokenId::new(dropped_tokens);
387393
let end_token = TokenId::new(dropped_tokens + tokens.len() - 1);
388394
TokenSpan::new(start_token, end_token)

0 commit comments

Comments
 (0)