rtlola_parser/
lib.rs

1//! A parser for RTLola specifications
2//!
3//! This crate offers functionality to transform a textual representation of an RTLola specification into an abstract syntax tree.  The Ast is not the most convenient data structure for
4//! modifying or analyzing a specification; there are other options available, outlined below.
5//!
6//! # Specification Representations
7//! * [RtLolaAst]: The Ast represents the abstract syntax of the specification.  It is obtained by first parsing the specification into a homogenous tree
8//!   and then remove concrete syntax fragments irrelevant for the logics of the specification.  Apart from that, the Ast does not provide much functionality.
9//!   The only checks performed when creating the Ast concern the correct syntax.  See also: [RtLolaAst], and [parse()].
10//! * [RtLolaHir](https://docs.rs/rtlola_hir/struct.RtLolaHir.html): The Hir represents a high-level intermediate representation optimized for analyzability.  It contains more convenient methods than the Ast, enables different
11//!   analysis steps and provides their reports.  The Hir traverses several modes representing the level to which it was analyzed and refined.
12//!   Its base mode is `RtLolaHir<BaseMode>` and its fully analyzed version is `RtLolaHir<CompleteMode>`.  See also: [rtlola_hir](https://docs.rs/rtlola_hir).
13//! * [RtLolaMir](https://docs.rs/rtlola_frontend/struct.RtLolaMir.html): The Mir represents a mid-level intermediate representation optimized for external use such as interpretation and compilation.  It contains several interconnections
14//!   enabling easy accesses and additional annotation such as memory bounds for each stream. See also: [rtlola_hir](https://docs.rs/rtlola_hir).
15//!   As a rule of thumb, if you want to analyze and/or enrich a specification, use the [RtLolaHir](https://docs.rs/rtlola_hir/struct.RtLolaHir.html).  If you only need a convenient representation of the specification for some devious
16//!   activity such as compiling it into something else, the [RtLolaMir](https://docs.rs/rtlola_frontend/struct.RtLolaMir.html) is the way to go.
17//!
18//! # Modules
19//! * [ast] Contains anything related to the [RtLolaAst].
20
21#![forbid(unused_must_use)] // disallow discarding errors
22#![warn(
23    missing_docs,
24    missing_debug_implementations,
25    missing_copy_implementations,
26    trivial_casts,
27    trivial_numeric_casts,
28    unsafe_code,
29    unstable_features,
30    unused_import_braces,
31    unused_qualifications
32)]
33
34mod parse;
35// Shall not be exposed; use parse function instead.
36mod syntactic_sugar;
37
38use std::fmt::Debug;
39use std::fs::File;
40use std::io::{self, Read};
41use std::path::PathBuf;
42
43// Public exports
44pub mod ast;
45
46pub use ast::RtLolaAst;
47use rtlola_reporting::{Handler, RtLolaError};
48
49/// The configuration of the parser.
50#[derive(Debug, Clone)]
51pub struct ParserConfig {
52    /// The path to the specification file that should be parsed
53    path: Option<PathBuf>,
54    /// The specification given as a string
55    spec: String,
56}
57
58impl ParserConfig {
59    /// Reads the specification from the given path and creates a new parser configuration for it.
60    pub fn from_path(path_to_spec: PathBuf) -> io::Result<Self> {
61        let mut file = File::open(&path_to_spec)?;
62        let mut spec = String::new();
63        file.read_to_string(&mut spec)?;
64        drop(file);
65        Ok(ParserConfig {
66            path: Some(path_to_spec),
67            spec,
68        })
69    }
70
71    /// Creates a new parser configuration for the given specification.
72    pub fn for_string(spec: String) -> Self {
73        ParserConfig { path: None, spec }
74    }
75
76    /// Creates a new parser configuration for the given specification using the name as file name.
77    pub fn for_named_spec(name: String, spec: String) -> Self {
78        ParserConfig {
79            path: Some(PathBuf::from(name)),
80            spec,
81        }
82    }
83
84    /// Invokes the parser on the specification given in the configuration.
85    pub fn parse(&self) -> Result<RtLolaAst, RtLolaError> {
86        parse(self)
87    }
88
89    /// Returns the path of the specification.
90    pub fn path(&self) -> &Option<PathBuf> {
91        &self.path
92    }
93
94    /// Returns the specification of the configuration.
95    pub fn spec(&self) -> &str {
96        &self.spec
97    }
98}
99
100/// Invokes the parser with the given configuration.
101pub fn parse(cfg: &ParserConfig) -> Result<RtLolaAst, RtLolaError> {
102    parse::RtLolaParser::parse(cfg)
103}
104
105impl<'a> From<&'a ParserConfig> for Handler<'a> {
106    fn from(cfg: &'a ParserConfig) -> Self {
107        match &cfg.path {
108            Some(path) => Handler::new(path, cfg.spec()),
109            None => Handler::without_file(cfg.spec()),
110        }
111    }
112}