Skip to content

Commit 6a892af

Browse files
authored
Add parsing context (#286)
1 parent 1233700 commit 6a892af

23 files changed

+1405
-1479
lines changed

vhdl_lang/src/syntax/alias_declaration.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,33 @@ use super::common::ParseResult;
88
use super::names::{parse_designator, parse_name};
99
use super::subprogram::parse_signature;
1010
use super::subtype_indication::parse_subtype_indication;
11-
use super::tokens::{Kind::*, TokenSpan, TokenStream};
11+
use super::tokens::{Kind::*, TokenSpan};
1212
use crate::ast::{AliasDeclaration, WithDecl};
13+
use vhdl_lang::syntax::parser::ParsingContext;
1314

14-
pub fn parse_alias_declaration(stream: &TokenStream) -> ParseResult<AliasDeclaration> {
15-
let start_token = stream.expect_kind(Alias)?;
16-
let designator = WithDecl::new(parse_designator(stream)?);
15+
pub fn parse_alias_declaration(ctx: &mut ParsingContext<'_>) -> ParseResult<AliasDeclaration> {
16+
let start_token = ctx.stream.expect_kind(Alias)?;
17+
let designator = WithDecl::new(parse_designator(ctx)?);
1718
let subtype_indication = {
18-
if stream.skip_if_kind(Colon) {
19-
Some(parse_subtype_indication(stream)?)
19+
if ctx.stream.skip_if_kind(Colon) {
20+
Some(parse_subtype_indication(ctx)?)
2021
} else {
2122
None
2223
}
2324
};
2425

25-
stream.expect_kind(Is)?;
26-
let name = parse_name(stream)?;
26+
ctx.stream.expect_kind(Is)?;
27+
let name = parse_name(ctx)?;
2728

2829
let signature = {
29-
if stream.peek_kind() == Some(LeftSquare) {
30-
Some(parse_signature(stream)?)
30+
if ctx.stream.peek_kind() == Some(LeftSquare) {
31+
Some(parse_signature(ctx)?)
3132
} else {
3233
None
3334
}
3435
};
3536

36-
let end_token = stream.expect_kind(SemiColon)?;
37+
let end_token = ctx.stream.expect_kind(SemiColon)?;
3738

3839
Ok(AliasDeclaration {
3940
span: TokenSpan::new(start_token, end_token),

vhdl_lang/src/syntax/attributes.rs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ use super::common::ParseResult;
88
use super::expression::parse_expression;
99
use super::names::parse_type_mark;
1010
use super::subprogram::parse_signature;
11-
use super::tokens::{Kind::*, TokenSpan, TokenStream};
11+
use super::tokens::{Kind::*, TokenSpan};
1212
use crate::ast::{
1313
Attribute, AttributeDeclaration, AttributeSpecification, Designator, EntityClass, EntityName,
1414
EntityTag, WithRef,
1515
};
16+
use vhdl_lang::syntax::parser::ParsingContext;
1617

17-
fn parse_entity_class(stream: &TokenStream) -> ParseResult<EntityClass> {
18-
Ok(expect_token!(stream, token,
18+
fn parse_entity_class(ctx: &mut ParsingContext<'_>) -> ParseResult<EntityClass> {
19+
Ok(expect_token!(ctx.stream, token,
1920
Entity => EntityClass::Entity,
2021
Architecture => EntityClass::Architecture,
2122
Configuration => EntityClass::Configuration,
@@ -35,8 +36,8 @@ fn parse_entity_class(stream: &TokenStream) -> ParseResult<EntityClass> {
3536
))
3637
}
3738

38-
pub fn parse_entity_name_list(stream: &TokenStream) -> ParseResult<Vec<EntityName>> {
39-
Ok(expect_token!(stream, token,
39+
pub fn parse_entity_name_list(ctx: &mut ParsingContext<'_>) -> ParseResult<Vec<EntityName>> {
40+
Ok(expect_token!(ctx.stream, token,
4041
Identifier | StringLiteral => {
4142
let mut entity_name_list = Vec::new();
4243
let mut token = token;
@@ -49,8 +50,8 @@ pub fn parse_entity_name_list(stream: &TokenStream) -> ParseResult<Vec<EntityNam
4950
};
5051

5152
let signature = {
52-
if stream.peek_kind() == Some(LeftSquare) {
53-
Some(parse_signature(stream)?)
53+
if ctx.stream.peek_kind() == Some(LeftSquare) {
54+
Some(parse_signature(ctx)?)
5455
} else {
5556
None
5657
}
@@ -61,8 +62,8 @@ pub fn parse_entity_name_list(stream: &TokenStream) -> ParseResult<Vec<EntityNam
6162
signature,
6263
}));
6364

64-
if stream.skip_if_kind(Comma) {
65-
token = expect_token!(stream, token, Identifier | StringLiteral => token);
65+
if ctx.stream.skip_if_kind(Comma) {
66+
token = expect_token!(ctx.stream, token, Identifier | StringLiteral => token);
6667
} else {
6768
break entity_name_list;
6869
}
@@ -77,26 +78,26 @@ pub fn parse_entity_name_list(stream: &TokenStream) -> ParseResult<Vec<EntityNam
7778
))
7879
}
7980

80-
pub fn parse_attribute(stream: &TokenStream) -> ParseResult<Vec<Attribute>> {
81-
let start_token = stream.expect_kind(Attribute)?;
82-
let ident = stream.expect_ident()?;
83-
Ok(expect_token!(stream, token,
81+
pub fn parse_attribute(ctx: &mut ParsingContext<'_>) -> ParseResult<Vec<Attribute>> {
82+
let start_token = ctx.stream.expect_kind(Attribute)?;
83+
let ident = ctx.stream.expect_ident()?;
84+
Ok(expect_token!(ctx.stream, token,
8485
Colon => {
85-
let type_mark = parse_type_mark(stream)?;
86-
let end_token = stream.expect_kind(SemiColon)?;
86+
let type_mark = parse_type_mark(ctx)?;
87+
let end_token = ctx.stream.expect_kind(SemiColon)?;
8788
vec![Attribute::Declaration(AttributeDeclaration {
8889
span: TokenSpan::new(start_token, end_token),
8990
ident: ident.into(),
9091
type_mark,
9192
})]
9293
},
9394
Of => {
94-
let entity_names = parse_entity_name_list(stream)?;
95-
stream.expect_kind(Colon)?;
96-
let entity_class = parse_entity_class(stream)?;
97-
stream.expect_kind(Is)?;
98-
let expr = parse_expression(stream)?;
99-
let end_token = stream.expect_kind(SemiColon)?;
95+
let entity_names = parse_entity_name_list(ctx)?;
96+
ctx.stream.expect_kind(Colon)?;
97+
let entity_class = parse_entity_class(ctx)?;
98+
ctx.stream.expect_kind(Is)?;
99+
let expr = parse_expression(ctx)?;
100+
let end_token = ctx.stream.expect_kind(SemiColon)?;
100101

101102
entity_names
102103
.into_iter()

vhdl_lang/src/syntax/common.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,25 @@
44
//
55
// Copyright (c) 2018, Olof Kraigher olof.kraigher@gmail.com
66

7-
use super::tokens::{Kind, TokenStream};
7+
use super::tokens::Kind;
88
use crate::ast::Ident;
99
use crate::data::Diagnostic;
10-
use crate::data::DiagnosticHandler;
1110
use crate::data::WithPos;
11+
use crate::syntax::parser::ParsingContext;
1212
use crate::SrcPos;
1313

1414
/// Parse optional part followed by optional keyword
1515
pub fn parse_optional<F, R>(
16-
stream: &TokenStream,
16+
ctx: &mut ParsingContext<'_>,
1717
keyword: Kind,
1818
parse_fun: F,
1919
) -> ParseResult<Option<R>>
2020
where
21-
F: FnOnce(&TokenStream) -> ParseResult<R>,
21+
F: FnOnce(&mut ParsingContext) -> ParseResult<R>,
2222
{
2323
let optional = {
24-
if stream.skip_if_kind(keyword) {
25-
Some(parse_fun(stream)?)
24+
if ctx.stream.skip_if_kind(keyword) {
25+
Some(parse_fun(ctx)?)
2626
} else {
2727
None
2828
}
@@ -32,15 +32,15 @@ where
3232
}
3333

3434
pub fn check_end_identifier_mismatch<T: std::fmt::Display + std::cmp::PartialEq>(
35+
ctx: &mut ParsingContext,
3536
ident: &WithPos<T>,
3637
end_ident: Option<WithPos<T>>,
37-
diagnostics: &mut dyn DiagnosticHandler,
3838
) -> Option<SrcPos> {
3939
if let Some(end_ident) = end_ident {
4040
if ident.item == end_ident.item {
4141
return Some(end_ident.pos);
4242
} else {
43-
diagnostics.push(Diagnostic::syntax_error(
43+
ctx.diagnostics.push(Diagnostic::syntax_error(
4444
&end_ident.pos,
4545
format!("End identifier mismatch, expected {}", ident.item),
4646
));
@@ -50,23 +50,23 @@ pub fn check_end_identifier_mismatch<T: std::fmt::Display + std::cmp::PartialEq>
5050
}
5151

5252
pub fn check_label_identifier_mismatch(
53+
ctx: &mut ParsingContext,
5354
label: Option<&Ident>,
5455
end_ident: Option<Ident>,
55-
diagnostics: &mut dyn DiagnosticHandler,
5656
) -> Option<SrcPos> {
5757
if let Some(ident) = label {
5858
if let Some(end_ident) = end_ident {
5959
if ident.item == end_ident.item {
6060
return Some(end_ident.pos);
6161
} else {
62-
diagnostics.push(Diagnostic::syntax_error(
62+
ctx.diagnostics.push(Diagnostic::syntax_error(
6363
&end_ident.pos,
6464
format!("End label mismatch, expected {}", ident.item),
6565
));
6666
}
6767
}
6868
} else if let Some(end_ident) = end_ident {
69-
diagnostics.push(Diagnostic::syntax_error(
69+
ctx.diagnostics.push(Diagnostic::syntax_error(
7070
&end_ident.pos,
7171
format!(
7272
"End label '{}' found for unlabeled statement",

vhdl_lang/src/syntax/component_declaration.rs

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,28 @@
44
//
55
// Copyright (c) 2018, Olof Kraigher olof.kraigher@gmail.com
66

7-
use super::common::check_end_identifier_mismatch;
8-
use super::common::ParseResult;
7+
use super::common::{check_end_identifier_mismatch, ParseResult};
98
use super::interface_declaration::{parse_generic_interface_list, parse_port_interface_list};
10-
use super::tokens::{Kind::*, TokenSpan, TokenStream};
9+
use super::tokens::{Kind::*, TokenSpan};
1110
use crate::ast::WithDecl;
1211
use crate::ast::{ComponentDeclaration, InterfaceDeclaration};
13-
use crate::data::{Diagnostic, DiagnosticHandler};
12+
use crate::data::Diagnostic;
13+
use vhdl_lang::syntax::parser::ParsingContext;
1414

1515
pub fn parse_optional_generic_list(
16-
stream: &TokenStream,
17-
diagnostics: &mut dyn DiagnosticHandler,
16+
ctx: &mut ParsingContext<'_>,
1817
) -> ParseResult<Option<Vec<InterfaceDeclaration>>> {
1918
let mut list = None;
2019
loop {
21-
let token = stream.peek_expect()?;
20+
let token = ctx.stream.peek_expect()?;
2221
match token.kind {
2322
Generic => {
24-
stream.skip();
25-
let new_list = parse_generic_interface_list(stream, diagnostics)?;
26-
stream.expect_kind(SemiColon)?;
23+
ctx.stream.skip();
24+
let new_list = parse_generic_interface_list(ctx)?;
25+
ctx.stream.expect_kind(SemiColon)?;
2726
if list.is_some() {
28-
diagnostics.push(Diagnostic::syntax_error(token, "Duplicate generic clause"));
27+
ctx.diagnostics
28+
.push(Diagnostic::syntax_error(token, "Duplicate generic clause"));
2929
} else {
3030
list = Some(new_list);
3131
}
@@ -38,28 +38,28 @@ pub fn parse_optional_generic_list(
3838
}
3939

4040
pub fn parse_optional_port_list(
41-
stream: &TokenStream,
42-
diagnostics: &mut dyn DiagnosticHandler,
41+
ctx: &mut ParsingContext<'_>,
4342
) -> ParseResult<Option<Vec<InterfaceDeclaration>>> {
4443
let mut list = None;
4544
loop {
46-
let token = stream.peek_expect()?;
45+
let token = ctx.stream.peek_expect()?;
4746
match token.kind {
4847
Port => {
49-
stream.skip();
50-
let new_list = parse_port_interface_list(stream, diagnostics)?;
51-
stream.expect_kind(SemiColon)?;
48+
ctx.stream.skip();
49+
let new_list = parse_port_interface_list(ctx)?;
50+
ctx.stream.expect_kind(SemiColon)?;
5251
if list.is_some() {
53-
diagnostics.push(Diagnostic::syntax_error(token, "Duplicate port clause"));
52+
ctx.diagnostics
53+
.push(Diagnostic::syntax_error(token, "Duplicate port clause"));
5454
} else {
5555
list = Some(new_list);
5656
}
5757
}
5858
Generic => {
59-
stream.skip();
60-
parse_generic_interface_list(stream, diagnostics)?;
61-
stream.expect_kind(SemiColon)?;
62-
diagnostics.push(Diagnostic::syntax_error(
59+
ctx.stream.skip();
60+
parse_generic_interface_list(ctx)?;
61+
ctx.stream.expect_kind(SemiColon)?;
62+
ctx.diagnostics.push(Diagnostic::syntax_error(
6363
token,
6464
"Generic clause must come before port clause",
6565
));
@@ -72,23 +72,22 @@ pub fn parse_optional_port_list(
7272
}
7373

7474
pub fn parse_component_declaration(
75-
stream: &TokenStream,
76-
diagnostics: &mut dyn DiagnosticHandler,
75+
ctx: &mut ParsingContext<'_>,
7776
) -> ParseResult<ComponentDeclaration> {
78-
let start_token = stream.expect_kind(Component)?;
79-
let ident = WithDecl::new(stream.expect_ident()?);
80-
stream.pop_if_kind(Is);
77+
let start_token = ctx.stream.expect_kind(Component)?;
78+
let ident = WithDecl::new(ctx.stream.expect_ident()?);
79+
ctx.stream.pop_if_kind(Is);
8180

82-
let generic_list = parse_optional_generic_list(stream, diagnostics)?;
83-
let port_list = parse_optional_port_list(stream, diagnostics)?;
84-
stream.expect_kind(End)?;
85-
stream.expect_kind(Component)?;
86-
let end_ident = stream.pop_optional_ident();
87-
let end_token = stream.expect_kind(SemiColon)?;
81+
let generic_list = parse_optional_generic_list(ctx)?;
82+
let port_list = parse_optional_port_list(ctx)?;
83+
ctx.stream.expect_kind(End)?;
84+
ctx.stream.expect_kind(Component)?;
85+
let end_ident = ctx.stream.pop_optional_ident();
86+
let end_token = ctx.stream.expect_kind(SemiColon)?;
8887

8988
Ok(ComponentDeclaration {
9089
span: TokenSpan::new(start_token, end_token),
91-
end_ident_pos: check_end_identifier_mismatch(&ident.tree, end_ident, diagnostics),
90+
end_ident_pos: check_end_identifier_mismatch(ctx, &ident.tree, end_ident),
9291
ident,
9392
generic_list: generic_list.unwrap_or_default(),
9493
port_list: port_list.unwrap_or_default(),

0 commit comments

Comments
 (0)