Skip to content

Commit fed579a

Browse files
committed
Simplify attribute designator parsing
1 parent d004b34 commit fed579a

File tree

3 files changed

+45
-53
lines changed

3 files changed

+45
-53
lines changed

vhdl_lang/src/syntax/names.rs

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use super::common::ParseResult;
99
use super::expression::{parse_expression, parse_expression_initial_token};
1010
use super::subprogram::parse_signature;
1111
use super::subtype_indication::parse_subtype_indication;
12-
use super::tokens::{Kind::*, Token, TokenStream, Value};
12+
use super::tokens::{Kind::*, Token, TokenStream};
1313
use crate::ast;
1414
use crate::ast::*;
1515
use crate::data::{Diagnostic, WithPos};
@@ -53,26 +53,18 @@ pub fn parse_type_mark_starting_with_name(
5353
// Check if it is a type mark with a subtype or element attribute:
5454
// Example: signal sig0 : sig1'subtype;
5555
if stream.pop_if_kind(Tick)?.is_some() {
56-
let subtype_token = stream.expect()?;
57-
if subtype_token.kind == Subtype {
58-
return Ok(WithPos {
59-
pos: subtype_token.pos.combine_into(&name.pos),
60-
item: TypeMark {
61-
name,
62-
attr: Some(TypeAttribute::Subtype),
63-
},
64-
});
65-
} else if subtype_token.kind == Identifier
66-
&& matches!(subtype_token.value, Value::Identifier(ref sym) if sym == stream.element_sym())
67-
{
68-
return Ok(WithPos {
69-
pos: subtype_token.pos.combine_into(&name.pos),
70-
item: TypeMark {
71-
name,
72-
attr: Some(TypeAttribute::Element),
73-
},
74-
});
56+
if let Ok(attr) = stream.expect_attribute_designator() {
57+
if let AttributeDesignator::Type(typattr) = attr.item {
58+
return Ok(WithPos {
59+
pos: attr.pos.combine_into(&name.pos),
60+
item: TypeMark {
61+
name,
62+
attr: Some(typattr),
63+
},
64+
});
65+
}
7566
}
67+
7668
stream.set_state(state);
7769
};
7870

vhdl_lang/src/syntax/tokens/tokenizer.rs

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

7-
use crate::ast::{self, Operator};
7+
use fnv::FnvHashMap;
8+
9+
use crate::ast::{self, AttributeDesignator, Operator};
810
use crate::ast::{BaseSpecifier, Ident};
911
use crate::data::*;
1012

@@ -1211,6 +1213,7 @@ fn get_trailing_comment(reader: &mut ContentReader) -> Result<Option<Comment>, T
12111213
pub struct Symbols {
12121214
symtab: SymbolTable,
12131215
keywords: Vec<Kind>,
1216+
attributes: FnvHashMap<Symbol, AttributeDesignator>,
12141217
}
12151218

12161219
impl Symbols {
@@ -1330,6 +1333,17 @@ impl std::default::Default for Symbols {
13301333
("vunit", Vunit),
13311334
];
13321335

1336+
let attributes = [
1337+
(
1338+
"reverse_range",
1339+
AttributeDesignator::Range(ast::RangeAttribute::ReverseRange),
1340+
),
1341+
(
1342+
"element",
1343+
AttributeDesignator::Type(ast::TypeAttribute::Element),
1344+
),
1345+
];
1346+
13331347
let symtab = SymbolTable::default();
13341348
let mut keywords = Vec::with_capacity(keywords_init.len());
13351349

@@ -1342,7 +1356,16 @@ impl std::default::Default for Symbols {
13421356
keywords.push(*kind);
13431357
}
13441358

1345-
Symbols { symtab, keywords }
1359+
let attributes = attributes
1360+
.into_iter()
1361+
.map(|(name, des)| (symtab.insert_utf8(name), des))
1362+
.collect();
1363+
1364+
Symbols {
1365+
symtab,
1366+
keywords,
1367+
attributes,
1368+
}
13461369
}
13471370
}
13481371

@@ -1353,8 +1376,6 @@ pub struct Tokenizer<'a> {
13531376
source: &'a Source,
13541377
reader: ContentReader<'a>,
13551378
final_comments: Option<Vec<Comment>>,
1356-
reverse_range_sym: Symbol,
1357-
element_sym: Symbol,
13581379
}
13591380

13601381
impl<'a> Tokenizer<'a> {
@@ -1363,20 +1384,13 @@ impl<'a> Tokenizer<'a> {
13631384
source: &'a Source,
13641385
reader: ContentReader<'a>,
13651386
) -> Tokenizer<'a> {
1366-
let reverse_range_sym = symbols
1367-
.symtab()
1368-
.insert(&Latin1String::new(b"reverse_range"));
1369-
let element_sym = symbols.symtab().insert(&Latin1String::new(b"element"));
1370-
13711387
Tokenizer {
13721388
symbols,
13731389
state: TokenState::new(reader.state()),
13741390
buffer: Latin1String::empty(),
13751391
source,
13761392
reader,
13771393
final_comments: None,
1378-
reverse_range_sym,
1379-
element_sym,
13801394
}
13811395
}
13821396

@@ -1402,12 +1416,12 @@ impl<'a> Tokenizer<'a> {
14021416
self.reader.set_state(self.state.start);
14031417
}
14041418

1405-
pub fn reverse_range_sym(&self) -> &Symbol {
1406-
&self.reverse_range_sym
1407-
}
1408-
1409-
pub fn element_sym(&self) -> &Symbol {
1410-
&self.element_sym
1419+
pub fn attribute(&self, sym: Symbol) -> AttributeDesignator {
1420+
self.symbols
1421+
.attributes
1422+
.get(&sym)
1423+
.cloned()
1424+
.unwrap_or_else(|| AttributeDesignator::Ident(sym))
14111425
}
14121426

14131427
fn parse_token(&mut self) -> Result<Option<(Kind, Value)>, TokenError> {

vhdl_lang/src/syntax/tokens/tokenstream.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use super::tokenizer::Kind::*;
88
use super::tokenizer::*;
99
use crate::ast::{AttributeDesignator, Ident, RangeAttribute, TypeAttribute};
10-
use crate::data::{DiagnosticHandler, DiagnosticResult, Symbol, WithPos};
10+
use crate::data::{DiagnosticHandler, DiagnosticResult, WithPos};
1111

1212
pub struct TokenStream<'a> {
1313
tokenizer: Tokenizer<'a>,
@@ -18,14 +18,6 @@ impl<'a> TokenStream<'a> {
1818
TokenStream { tokenizer }
1919
}
2020

21-
pub fn reverse_range_sym(&self) -> &Symbol {
22-
self.tokenizer.reverse_range_sym()
23-
}
24-
25-
pub fn element_sym(&self) -> &Symbol {
26-
self.tokenizer.element_sym()
27-
}
28-
2921
pub fn state(&self) -> TokenState {
3022
self.tokenizer.state()
3123
}
@@ -144,13 +136,7 @@ impl<'a> TokenStream<'a> {
144136
token,
145137
Identifier => {
146138
let ident = token.expect_ident()?;
147-
if &ident.item == self.reverse_range_sym() {
148-
ident.map_into(|_| AttributeDesignator::Range(RangeAttribute::ReverseRange))
149-
} else if &ident.item == self.element_sym() {
150-
ident.map_into(|_| AttributeDesignator::Type(TypeAttribute::Element))
151-
} else {
152-
ident.map_into(AttributeDesignator::Ident)
153-
}
139+
ident.map_into(|sym| self.tokenizer.attribute(sym))
154140
},
155141
Subtype => WithPos::new(AttributeDesignator::Type(TypeAttribute::Subtype), token.pos),
156142
Range => WithPos::new(AttributeDesignator::Range(RangeAttribute::Range), token.pos)

0 commit comments

Comments
 (0)