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+
914mod error;
1015mod lexer;
1116mod parser;
@@ -14,16 +19,27 @@ use std::{ops, str::FromStr};
1419
1520pub use error:: { Error , Result } ;
1621
22+ /// Returns a Rust grammar.
1723pub 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 ) ]
2333pub 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 ) ]
2540pub struct Token ( usize ) ;
2641
42+ /// An Ungrammar grammar.
2743#[ derive( Default , Debug ) ]
2844pub struct Grammar {
2945 nodes : Vec < NodeData > ,
@@ -39,9 +55,15 @@ impl FromStr for Grammar {
3955}
4056
4157impl 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
4769impl 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 ) ]
6285pub 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 ) ]
6898pub struct TokenData {
99+ /// The name of the token.
69100 pub name : String ,
70101}
71102
103+ /// A production rule.
72104#[ derive( Debug , Eq , PartialEq ) ]
73105pub 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