Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | lib/ungrammar/src/error.rs | 2 | ||||
| -rw-r--r-- | lib/ungrammar/src/lib.rs | 36 |
2 files changed, 37 insertions, 1 deletions
diff --git a/lib/ungrammar/src/error.rs b/lib/ungrammar/src/error.rs index a7a62d0cc0..6cc86f52f9 100644 --- a/lib/ungrammar/src/error.rs +++ b/lib/ungrammar/src/error.rs @@ -3,8 +3,10 @@ use std::fmt; use crate::lexer::Location; +/// A type alias for std's Result with the Error as our error type. pub type Result<T, E = Error> = std::result::Result<T, E>; +/// An error encountered when parsing a Grammar. #[derive(Debug)] pub struct Error { pub(crate) message: String, diff --git a/lib/ungrammar/src/lib.rs b/lib/ungrammar/src/lib.rs index 228952389f..7d7c14f535 100644 --- a/lib/ungrammar/src/lib.rs +++ b/lib/ungrammar/src/lib.rs @@ -6,6 +6,11 @@ //! See this //! [introductory post](https://rust-analyzer.github.io/blog/2020/10/24/introducing-ungrammar.html) //! for details. + +#![deny(missing_debug_implementations)] +#![deny(missing_docs)] +#![deny(rust_2018_idioms)] + mod error; mod lexer; mod parser; @@ -14,16 +19,21 @@ use std::{ops, str::FromStr}; pub use error::{Error, Result}; +/// Returns a Rust grammar. pub fn rust_grammar() -> Grammar { let src = include_str!("../rust.ungram"); src.parse().unwrap() } +/// A node, like `A = 'b' | 'c'`. #[derive(Eq, PartialEq, Debug, Copy, Clone, Hash, PartialOrd, Ord)] pub struct Node(usize); + +/// A token, denoted with single quotes, like `'+'` or `'struct'`. #[derive(Eq, PartialEq, Debug, Copy, Clone, Hash, PartialOrd, Ord)] pub struct Token(usize); +/// An Ungrammar grammar. #[derive(Default, Debug)] pub struct Grammar { nodes: Vec<NodeData>, @@ -39,10 +49,12 @@ impl FromStr for Grammar { } impl Grammar { + /// Returns an iterator over all nodes in the grammar. pub fn iter(&self) -> impl Iterator<Item = Node> + '_ { (0..self.nodes.len()).map(Node) } + /// Returns an iterator over all tokens in the grammar. pub fn tokens(&self) -> impl Iterator<Item = Token> + '_ { (0..self.tokens.len()).map(Token) } @@ -62,25 +74,47 @@ impl ops::Index<Token> for Grammar { } } +/// Data about a node. #[derive(Debug)] pub struct NodeData { + /// The name of the node. + /// + /// In the rule `A = 'b' | 'c'`, this is `"A"`. pub name: String, + /// The rule for this node. + /// + /// In the rule `A = 'b' | 'c'`, this represents `'b' | 'c'`. pub rule: Rule, } +/// Data about a token. #[derive(Debug)] pub struct TokenData { + /// The name of the token. pub name: String, } +/// A production rule. #[derive(Debug, Eq, PartialEq)] pub enum Rule { - Labeled { label: String, rule: Box<Rule> }, + /// A labeled rule, like `a:B` (`"a"` is the label, `B` is the rule). + Labeled { + /// The label. + label: String, + /// The rule. + rule: Box<Rule>, + }, + /// A node, like `A`. Node(Node), + /// A token, like `'struct'`. Token(Token), + /// A sequence of rules, like `'while' '(' Expr ')' Stmt`. Seq(Vec<Rule>), + /// An alternative between many rules, like `'+' | '-' | '*' | '/'`. Alt(Vec<Rule>), + /// An optional rule, like `A?`. Opt(Box<Rule>), + /// An repeated rule, like `A*`. Rep(Box<Rule>), } |