open_vaf/parser/
mod.rs

1/*
2 * ******************************************************************************************
3 * Copyright (c) 2019 Pascal Kuthe. This file is part of the OpenVAF project.
4 * It is subject to the license terms in the LICENSE file found in the top-level directory
5 *  of this distribution and at  https://gitlab.com/DSPOM/OpenVAF/blob/master/LICENSE.
6 *  No part of OpenVAF, including this file, may be copied, modified, propagated, or
7 *  distributed except according to the terms contained in the LICENSE file.
8 * *****************************************************************************************
9 */
10use std::path::Path;
11
12use bumpalo::Bump;
13use log::*;
14
15pub use error::Error;
16pub use error::Result;
17
18use crate::ast::{Ast, HierarchicalId};
19use crate::ir::{Attribute, AttributeId, Attributes};
20use crate::parser::error::{Expected, Type, Warning, WarningType};
21use crate::parser::lexer::Token;
22use crate::span::Index;
23use crate::symbol::{keywords, Ident, Symbol};
24use crate::symbol_table::{SymbolDeclaration, SymbolTable};
25use crate::{Preprocessor, SourceMap, Span};
26use rustc_hash::FxHashMap;
27
28pub(crate) mod lexer;
29pub(crate) mod preprocessor;
30#[cfg(test)]
31pub mod test;
32
33#[macro_use]
34mod combinators;
35mod behavior;
36mod branch;
37mod disciplines;
38pub mod error;
39mod expression;
40mod module;
41mod nature;
42mod net_declarations;
43mod parameter;
44mod primaries;
45mod variables;
46
47/// A reclusive decent Parser that parses the tokens created by the [`Preprocessor`](crate::parser::preprocessor::Preprocessor) into an [`Ast`](crate::ast::Ast).
48pub(crate) struct Parser<'lt, 'source_map> {
49    pub preprocessor: Preprocessor<'lt, 'source_map>,
50    pub scope_stack: Vec<SymbolTable>,
51    lookahead: Option<Result<(Token, Span, Index)>>,
52    pub ast: &'lt mut Ast,
53    pub non_critical_errors: Vec<Error>,
54    pub warnings: Vec<Warning>,
55    pub(crate) unrecoverable: bool,
56}
57
58impl<'lt, 'source_map> Parser<'lt, 'source_map> {
59    pub fn new(
60        preprocessor: Preprocessor<'lt, 'source_map>,
61        ast: &'lt mut Ast,
62        errors: Vec<Error>,
63    ) -> Self {
64        Self {
65            preprocessor,
66            scope_stack: Vec::with_capacity(32),
67            lookahead: None,
68            ast,
69            non_critical_errors: errors,
70            warnings: Vec::with_capacity(32),
71            unrecoverable: false,
72        }
73    }
74
75    pub fn run(&mut self) {
76        synchronize!(self;
77            let attributes = self.parse_attributes()?;
78            sync self.next_with_span() => {
79                Token::EOF => end,
80                Token::Module => self.parse_module(attributes),
81                Token::Nature => self.parse_nature(attributes),
82                Token::Discipline => self.parse_discipline(attributes),
83            }
84        )
85    }
86    /// Returns the next token. Note that this consumes the token. If you wish to avoid this use [`look_ahead`](crate::parser::Parser::look_ahead)
87    fn next(&mut self) -> Result<Token> {
88        match self.lookahead.take() {
89            None => {
90                self.preprocessor.advance()?;
91                Ok(self.preprocessor.current_token())
92            }
93            Some(res) => res.map(|(token, _, _)| token),
94        }
95    }
96
97    /// Returns the next token and its span. Note that this consumes the token. If you wish to avoid this use [`look_ahead_with_span`](crate::parser::Parser::look_ahead_with_span)
98    fn next_with_span(&mut self) -> Result<(Token, Span)> {
99        match self.lookahead.take() {
100            None => {
101                self.preprocessor.advance()?;
102                Ok((self.preprocessor.current_token(), self.preprocessor.span()))
103            }
104            Some(res) => res.map(|(token, span, _)| (token, span)),
105        }
106    }
107
108    /// Returns the next token and its span. Note that this consumes the token. If you wish to avoid this use [`look_ahead_with_span_and_previous_end`](crate::parser::Parser::look_ahead_with_span_and_previous_end)
109    fn next_with_span_and_previous_end(&mut self) -> Result<(Token, Span, Index)> {
110        match self.lookahead.take() {
111            None => {
112                let end = self.preprocessor.current_end();
113                self.preprocessor.advance()?;
114                Ok((
115                    self.preprocessor.current_token(),
116                    self.preprocessor.span(),
117                    end,
118                ))
119            }
120            Some(res) => res,
121        }
122    }
123
124    /// Returns the next token without consuming it so the next `look_ahead`/[`next`](crate::parser::Parser::next) call will return the same token again
125    /// if you do decide to consume the token use [`consume_lookahead`](crate::parser::Parser::consume_lookahead)
126    fn look_ahead(&mut self) -> Result<Token> {
127        if let Some(ref lookahead) = self.lookahead {
128            return lookahead.clone().map(|(token, _, _)| token);
129        }
130        let end = self.preprocessor.current_end();
131        let res = self.preprocessor.advance().map(|_| {
132            (
133                self.preprocessor.current_token(),
134                self.preprocessor.span(),
135                end,
136            )
137        });
138        self.lookahead = Some(res.clone());
139        res.map(|(token, _, _)| token)
140    }
141
142    /// Returns the next token and its span without consuming it so the next `look_ahead`/[`next`](crate::parser::Parser::next) call will return the same token again
143    /// if you do decide to consume the token use [`consume_lookahead`](crate::parser::Parser::consume_lookahead)
144    fn look_ahead_with_span(&mut self) -> Result<(Token, Span)> {
145        if let Some(ref lookahead) = self.lookahead {
146            return lookahead.clone().map(|(token, span, _)| (token, span));
147        }
148        let end = self.preprocessor.current_end();
149        let res = self.preprocessor.advance().map(|_| {
150            (
151                self.preprocessor.current_token(),
152                self.preprocessor.span(),
153                end,
154            )
155        });
156        self.lookahead = Some(res.clone());
157        res.map(|(token, span, _)| (token, span))
158    }
159
160    /// Returns the next token, its span and the end of the previous token without consuming it so the next `look_ahead`/[`next`](crate::parser::Parser::next) call will return the same token again
161    /// if you do decide to consume the token use [`consume_lookahead`](crate::parser::Parser::consume_lookahead)
162    fn look_ahead_with_span_and_previous_end(&mut self) -> Result<(Token, Span, Index)> {
163        if let Some(ref lookahead) = self.lookahead {
164            return lookahead.clone();
165        }
166        let end = self.preprocessor.current_end();
167        let res = self.preprocessor.advance().map(|_| {
168            (
169                self.preprocessor.current_token(),
170                self.preprocessor.span(),
171                end,
172            )
173        });
174        self.lookahead = Some(res.clone());
175        res
176    }
177
178    /// Consumes the current lookahead see [`look_ahead`](crate::parser::Parser::look_ahead)
179    fn consume_lookahead(&mut self) {
180        self.lookahead = None
181    }
182
183    /// Parses any of the two identifiers legal in verilog-ams (see standard for more details):
184    ///
185    /// * Normal identifiers
186    ///
187    /// * Escaped identifiers - Starting with `\` and ending with a Whitespace are allow
188    ///
189    ///
190    /// # Arguments
191    /// `optional` - Indicates that parsing the identifier is optional.
192    /// In that case [`look_ahead`](crate::parser::Parser::look_ahead) is used instead of `next` to allow easier recovery
193    ///
194    #[inline]
195    pub fn parse_identifier(&mut self, optional: bool) -> Result<Ident> {
196        let (token, source) = if optional {
197            self.look_ahead_with_span()?
198        } else {
199            self.next_with_span()?
200        };
201
202        let identifier = match token {
203            Token::SimpleIdentifier(_) => self.preprocessor.slice(),
204
205            Token::EscapedIdentifier => {
206                let raw = self.preprocessor.slice();
207                &raw[1..raw.len() - 1]
208            }
209
210            _ => {
211                return Err(Error {
212                    source,
213                    error_type: error::Type::UnexpectedTokens {
214                        expected: vec![Expected::Identifier],
215                    },
216                })
217            }
218        };
219
220        if optional {
221            self.consume_lookahead();
222        }
223
224        Ok(Ident::from_str_and_span(identifier, source))
225    }
226
227    /// Parses and hierarchical identifier. A hieraichal Identifiers is a [normal identifier](crate::parser::Parser::parse_identifier) follow by an arbitrary amount of additional identifiers separated by a `.`
228    ///
229    ///
230    /// # Examples
231    /// This function can parse all of the following examples
232    ///
233    /// ```Verilog
234    ///  foo
235    ///  foo.bar
236    ///  foo.bar.x
237    ///  \Escaped.Identifier .bar
238    /// ```
239
240    pub fn parse_hierarchical_identifier(&mut self) -> Result<HierarchicalId> {
241        //Since hierarchical_identifier are made up of multiple lexer tokens they can not be parsed optionally.
242        // This will have to be handled by caller so we just pass false to parse_identifier
243        let mut names = vec![self.parse_identifier(false)?];
244        while self.look_ahead()? == Token::Accessor {
245            self.consume_lookahead();
246            names.push(self.parse_identifier(false)?)
247        }
248        Ok(HierarchicalId { names })
249    }
250
251    /// Parses the attributes before an item. According to the Verilog-Ams standard an arbitrary amount of attribute lists may be specified for each item
252    /// An attribute list is an arbitrary amount of [attributes](crate::parser::Parser::parse_attribute)  separated by `,` and wrapped inside `(*` and `*)`
253    ///
254    ///
255    /// # Examples
256    ///
257    /// This function can parse all of the following examples
258    ///
259    /// ``` Verilog
260    /// /* No attributes */
261    /// (*x,y=2*) //parsed attributes: (x:0,y:2)
262    /// (*x,z="test"*)(*y=2*)(*x=1,y=3*) //parsed attributes x=1
263    /// ```
264    ///
265    pub fn parse_attributes(&mut self) -> Result<Attributes> {
266        let attr_start = self.ast.attributes.len_idx();
267        let mut attribute_map: FxHashMap<Symbol, AttributeId> = FxHashMap::default();
268        loop {
269            if self.look_ahead()? != Token::AttributeStart {
270                break;
271            }
272            self.consume_lookahead();
273            self.parse_list(
274                |sel| sel.parse_attribute(&mut attribute_map),
275                Token::AttributeEnd,
276                true,
277            )?;
278        }
279        Ok(Attributes::new(attr_start, self.ast.attributes.len_idx()))
280    }
281
282    /// Parses a single attribute of the form `name = value` (value may be any valid constant expression that doesn't reference a parameter or Literal*) inside an Attribute Lis.
283    /// Specifying a value is optional so just `name` is also valid (in this case the value is 0) .
284    /// If this Attribute is already defined for the current item it will be overwritten and a Warning will be generated
285    fn parse_attribute(&mut self, attribute_map: &mut FxHashMap<Symbol, AttributeId>) -> Result {
286        let name = if self.look_ahead()? == Token::Units {
287            self.consume_lookahead();
288            Ident::new(keywords::UNITS, self.preprocessor.span())
289        } else {
290            self.parse_identifier(false)?
291        };
292        let value = if self.look_ahead()? == Token::Assign {
293            self.consume_lookahead();
294            Some(self.parse_expression_id()?)
295        } else {
296            None
297        };
298        if let Some(id) = attribute_map.get(&name.name) {
299            let old_name = self.ast[*id].name;
300            self.warnings.push(Warning {
301                error_type: WarningType::AttributeOverwrite(old_name, name.span),
302                source: old_name.span.extend(name.span),
303            });
304            self.ast[*id] = Attribute { name, value };
305        } else {
306            let id = self.ast.attributes.push(Attribute { name, value });
307            attribute_map.insert(name.name, id);
308        }
309        Ok(())
310    }
311
312    /// Tries to consume `token` returns an Unexpected Token error otherwise
313    #[inline]
314    pub fn expect(&mut self, token: Token) -> Result {
315        let (found, source, expected_at) = self.next_with_span_and_previous_end()?;
316        if found == token {
317            Ok(())
318        } else {
319            debug!("Parser: Expected {} but found {}", token, found);
320            Err(Error {
321                source,
322                error_type: error::Type::MissingOrUnexpectedToken {
323                    expected: vec![token],
324                    expected_at,
325                },
326            })
327        }
328    }
329
330    #[inline]
331    pub fn try_expect(&mut self, token: Token) {
332        match self.look_ahead_with_span_and_previous_end() {
333            Ok((found, _, _)) if found == token => {
334                self.consume_lookahead();
335            }
336            Ok((found, source, expected_at)) if found == Token::Unexpected => {
337                debug!(
338                    "Parser: Expected {} but found {} lexical error",
339                    token, found
340                );
341                self.consume_lookahead();
342                self.non_critical_errors.push(Error {
343                    source,
344                    error_type: error::Type::MissingOrUnexpectedToken {
345                        expected: vec![found],
346                        expected_at,
347                    },
348                })
349            }
350            Err(error) => {
351                debug!("Parser: Expected {} but found preprocessor error", token);
352                self.consume_lookahead();
353                self.non_critical_errors.push(error)
354            }
355            Ok((found, source, expected_at)) => {
356                debug!(
357                    "Parser: Expected {} but found {} (not consumed)",
358                    token, found
359                );
360                self.non_critical_errors.push(Error {
361                    source,
362                    error_type: error::Type::MissingOrUnexpectedToken {
363                        expected: vec![token],
364                        expected_at,
365                    },
366                });
367            }
368        }
369    }
370
371    #[inline]
372    pub fn expect_lookahead(&mut self, token: Token) -> Result {
373        let (found, source, expected_at) = self.look_ahead_with_span_and_previous_end()?;
374        if found == token {
375            self.consume_lookahead();
376            Ok(())
377        } else {
378            Err(Error {
379                source,
380                error_type: error::Type::MissingOrUnexpectedToken {
381                    expected: vec![token],
382                    expected_at,
383                },
384            })
385        }
386    }
387
388    #[inline]
389    pub fn span_to_current_end(&self, start: Index) -> Span {
390        Span::new(start, self.preprocessor.current_end())
391    }
392
393    #[inline]
394    pub fn insert_symbol(&mut self, name: Ident, declaration: SymbolDeclaration) {
395        let source = declaration.span(&self.ast);
396        if let Some(old_declaration) = self.symbol_table_mut().insert(name.name, declaration) {
397            self.non_critical_errors.push(Error {
398                error_type: Type::AlreadyDeclaredInThisScope {
399                    other_declaration: old_declaration.span(&self.ast),
400                    name: name.name,
401                },
402                source,
403            });
404        }
405    }
406
407    #[inline]
408    pub fn symbol_table_mut(&mut self) -> &mut SymbolTable {
409        self.scope_stack
410            .last_mut()
411            .unwrap_or(&mut self.ast.top_symbols)
412    }
413
414    #[inline]
415    pub fn symbol_table(&self) -> &SymbolTable {
416        self.scope_stack.last().unwrap_or(&self.ast.top_symbols)
417    }
418}
419
420impl Ast {
421    /// The main point of this module. Parses a verilog-ams source file into an ast and returns any errors that occur
422    ///
423    /// # Arguments
424    ///
425    /// * `main_file` - The Verilog-A source file to parse
426    ///
427    /// * `source_map_allocator` - A bump allocator that will be used to allocate the source map.
428    /// (`Bump::new()` can be used to create one)
429    ///
430    ///
431    /// # Returns
432    ///
433    /// * An **Io Error** if the `main_file` could not be read
434    /// * A [`SourceMap`](crate::parser::preprocessor::SourceMap) of the parsed file generated during parsing
435    /// * A list of all Errors that occurred during parsing
436    /// * A list of all Warnings generated during parsing
437
438    pub fn parse_from<'source_map, 'lt>(
439        &'lt mut self,
440        main_file: &Path,
441        source_map_allocator: &'source_map Bump,
442    ) -> std::io::Result<(
443        &'source_map SourceMap<'source_map>,
444        Vec<Error>,
445        Vec<Warning>,
446    )> {
447        let allocator = Bump::new();
448
449        let mut preprocessor = Preprocessor::new(&allocator, source_map_allocator, main_file)?;
450
451        let mut errors = Vec::with_capacity(64);
452        if let Err(error) = preprocessor.advance() {
453            errors.push(error);
454        }
455
456        let mut parser = Parser::new(preprocessor, self, errors);
457
458        // The preprocessors current token is set to the first token after initialization.
459        // The parsers lookahead needs to be set to this token as it is skipped otherwise
460        parser.lookahead = Some(Ok((
461            parser.preprocessor.current_token(),
462            parser.preprocessor.span(),
463            0,
464        )));
465
466        parser.run();
467
468        Ok((
469            parser.preprocessor.done(),
470            parser.non_critical_errors,
471            parser.warnings,
472        ))
473    }
474
475    /// Parses a verilog-ams source file into an ast and prints any errors that occur
476    ///
477    /// # Arguments
478    ///
479    /// * `main_file` - The Verilog-A source file to parse
480    ///
481    /// * `source_map_allocator` - A bump allocator that will be used to allocate the source map.
482    /// (`Bump::new()` can be used to create one)
483    ///
484    /// * `translate_lines` - When this is set to true the line numbers of printed errors are translated
485    /// to reflect the line in the original source file instead of the source that was expanded by the preprocessor
486    ///
487    /// # Returns
488    /// * **Parse successful** - A Source Map of the parsed source
489    /// * **Errors occurred during** - Prints the errors and returns `None`
490    pub fn parse_from_and_print_errors<'source_map, 'lt>(
491        &'lt mut self,
492        main_file: &Path,
493        source_map_allocator: &'source_map Bump,
494        translate_lines: bool,
495    ) -> Option<&'source_map SourceMap<'source_map>> {
496        match self.parse_from(main_file, source_map_allocator) {
497            Ok((source_map, errors, warnings)) if errors.is_empty() => {
498                warnings
499                    .into_iter()
500                    .for_each(|warning| warning.print(source_map, translate_lines));
501                Some(source_map)
502            }
503            Ok((source_map, errors, warnings)) => {
504                warnings
505                    .into_iter()
506                    .for_each(|warning| warning.print(source_map, translate_lines));
507                errors
508                    .into_iter()
509                    .for_each(|err| err.print(&source_map, translate_lines));
510                None
511            }
512            Err(error) => {
513                error!("failed to open : {}!\n\t caused by {}",main_file.display(),error);
514                None
515            }
516        }
517    }
518}