Skip to content

Commit 5846451

Browse files
bors[bot]azdavis
andauthored
Merge #25
25: Derive more traits for Node and Token r=azdavis a=azdavis - Derive Hash for Node and Token - I'd like to be able to use these types as keys for a HashMap - Derive PartialOrd and Ord as well - I don't particularly need these but perhaps if someone wanted to put them into a BTreeMap it might be handy - Add an iterator for tokens of a grammar - Write docs - Enforce some lints Co-authored-by: Ariel Davis <ariel.z.davis@icloud.com>
2 parents 3e99ee1 + e4e81fe commit 5846451

File tree

4 files changed

+52
-5
lines changed

4 files changed

+52
-5
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "ungrammar"
33
description = "A DSL for describing concrete syntax trees"
4-
version = "1.9.3"
4+
version = "1.10.0"
55
license = "MIT OR Apache-2.0"
66
repository = "https://github.com/matklad/ungrammar"
77
authors = ["Aleksey Kladov <aleksey.kladov@gmail.com>"]

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# ungrammar
22

3-
A DLS for specifying concrete syntax tree. See this [introductory post](https://rust-analyzer.github.io/blog/2020/10/24/introducing-ungrammar.html).
3+
A DSL for specifying concrete syntax trees. See this
4+
[introductory post](https://rust-analyzer.github.io/blog/2020/10/24/introducing-ungrammar.html).
45

56
See [./rust.ungram](./rust.ungram) for an example.

src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ use std::fmt;
33

44
use crate::lexer::Location;
55

6+
/// A type alias for std's Result with the Error as our error type.
67
pub type Result<T, E = Error> = std::result::Result<T, E>;
78

9+
/// An error encountered when parsing a Grammar.
810
#[derive(Debug)]
911
pub struct Error {
1012
pub(crate) message: String,

src/lib.rs

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
//! See this
77
//! [introductory post](https://rust-analyzer.github.io/blog/2020/10/24/introducing-ungrammar.html)
88
//! for details.
9+
10+
#![deny(missing_debug_implementations)]
11+
#![deny(missing_docs)]
12+
#![deny(rust_2018_idioms)]
13+
914
mod error;
1015
mod lexer;
1116
mod parser;
@@ -14,16 +19,27 @@ use std::{ops, str::FromStr};
1419

1520
pub use error::{Error, Result};
1621

22+
/// Returns a Rust grammar.
1723
pub fn rust_grammar() -> Grammar {
1824
let src = include_str!("../rust.ungram");
1925
src.parse().unwrap()
2026
}
2127

22-
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
28+
/// A node, like `A = 'b' | 'c'`.
29+
///
30+
/// Indexing into a [`Grammar`] with a [`Node`] returns a reference to a
31+
/// [`NodeData`].
32+
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
2333
pub struct Node(usize);
24-
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
34+
35+
/// A token, denoted with single quotes, like `'+'` or `'struct'`.
36+
///
37+
/// Indexing into a [`Grammar`] with a [`Token`] returns a reference to a
38+
/// [`TokenData`].
39+
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
2540
pub struct Token(usize);
2641

42+
/// An Ungrammar grammar.
2743
#[derive(Default, Debug)]
2844
pub struct Grammar {
2945
nodes: Vec<NodeData>,
@@ -39,9 +55,15 @@ impl FromStr for Grammar {
3955
}
4056

4157
impl Grammar {
58+
/// Returns an iterator over all nodes in the grammar.
4259
pub fn iter(&self) -> impl Iterator<Item = Node> + '_ {
4360
(0..self.nodes.len()).map(Node)
4461
}
62+
63+
/// Returns an iterator over all tokens in the grammar.
64+
pub fn tokens(&self) -> impl Iterator<Item = Token> + '_ {
65+
(0..self.tokens.len()).map(Token)
66+
}
4567
}
4668

4769
impl ops::Index<Node> for Grammar {
@@ -58,25 +80,47 @@ impl ops::Index<Token> for Grammar {
5880
}
5981
}
6082

83+
/// Data about a node.
6184
#[derive(Debug)]
6285
pub struct NodeData {
86+
/// The name of the node.
87+
///
88+
/// In the rule `A = 'b' | 'c'`, this is `"A"`.
6389
pub name: String,
90+
/// The rule for this node.
91+
///
92+
/// In the rule `A = 'b' | 'c'`, this represents `'b' | 'c'`.
6493
pub rule: Rule,
6594
}
6695

96+
/// Data about a token.
6797
#[derive(Debug)]
6898
pub struct TokenData {
99+
/// The name of the token.
69100
pub name: String,
70101
}
71102

103+
/// A production rule.
72104
#[derive(Debug, Eq, PartialEq)]
73105
pub enum Rule {
74-
Labeled { label: String, rule: Box<Rule> },
106+
/// A labeled rule, like `a:B` (`"a"` is the label, `B` is the rule).
107+
Labeled {
108+
/// The label.
109+
label: String,
110+
/// The rule.
111+
rule: Box<Rule>,
112+
},
113+
/// A node, like `A`.
75114
Node(Node),
115+
/// A token, like `'struct'`.
76116
Token(Token),
117+
/// A sequence of rules, like `'while' '(' Expr ')' Stmt`.
77118
Seq(Vec<Rule>),
119+
/// An alternative between many rules, like `'+' | '-' | '*' | '/'`.
78120
Alt(Vec<Rule>),
121+
/// An optional rule, like `A?`.
79122
Opt(Box<Rule>),
123+
/// A repeated rule, like `A*`.
80124
Rep(Box<Rule>),
81125
}
82126

0 commit comments

Comments
 (0)