]> git.proxmox.com Git - rustc.git/blob - vendor/rowan/examples/math.rs
New upstream version 1.46.0~beta.2+dfsg1
[rustc.git] / vendor / rowan / examples / math.rs
1 //! Example that takes the input
2 //! 1 + 2 * 3 + 4
3 //! and builds the tree
4 //! - Marker(Root)
5 //! - Marker(Operation)
6 //! - Marker(Operation)
7 //! - "1" Token(Number)
8 //! - "+" Token(Add)
9 //! - Marker(Operation)
10 //! - "2" Token(Number)
11 //! - "*" Token(Mul)
12 //! - "3" Token(Number)
13 //! - "+" Token(Add)
14 //! - "4" Token(Number)
15
16 use rowan::{GreenNodeBuilder, NodeOrToken, SmolStr};
17 use std::iter::Peekable;
18
19 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
20 #[allow(non_camel_case_types)]
21 #[repr(u16)]
22 enum SyntaxKind {
23 WHITESPACE = 0,
24
25 ADD,
26 SUB,
27 MUL,
28 DIV,
29
30 NUMBER,
31 ERROR,
32 OPERATION,
33 ROOT,
34 }
35 use SyntaxKind::*;
36
37 impl From<SyntaxKind> for rowan::SyntaxKind {
38 fn from(kind: SyntaxKind) -> Self {
39 Self(kind as u16)
40 }
41 }
42
43 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
44 enum Lang {}
45 impl rowan::Language for Lang {
46 type Kind = SyntaxKind;
47 fn kind_from_raw(raw: rowan::SyntaxKind) -> Self::Kind {
48 assert!(raw.0 <= ROOT as u16);
49 unsafe { std::mem::transmute::<u16, SyntaxKind>(raw.0) }
50 }
51 fn kind_to_raw(kind: Self::Kind) -> rowan::SyntaxKind {
52 kind.into()
53 }
54 }
55
56 type SyntaxNode = rowan::SyntaxNode<Lang>;
57 #[allow(unused)]
58 type SyntaxToken = rowan::SyntaxToken<Lang>;
59 #[allow(unused)]
60 type SyntaxElement = rowan::NodeOrToken<SyntaxNode, SyntaxToken>;
61
62 struct Parser<I: Iterator<Item = (SyntaxKind, SmolStr)>> {
63 builder: GreenNodeBuilder<'static>,
64 iter: Peekable<I>,
65 }
66 impl<I: Iterator<Item = (SyntaxKind, SmolStr)>> Parser<I> {
67 fn peek(&mut self) -> Option<SyntaxKind> {
68 while self.iter.peek().map(|&(t, _)| t == WHITESPACE).unwrap_or(false) {
69 self.bump();
70 }
71 self.iter.peek().map(|&(t, _)| t)
72 }
73 fn bump(&mut self) {
74 if let Some((token, string)) = self.iter.next() {
75 self.builder.token(token.into(), string);
76 }
77 }
78 fn parse_val(&mut self) {
79 match self.peek() {
80 Some(NUMBER) => self.bump(),
81 _ => {
82 self.builder.start_node(ERROR.into());
83 self.bump();
84 self.builder.finish_node();
85 }
86 }
87 }
88 fn handle_operation(&mut self, tokens: &[SyntaxKind], next: fn(&mut Self)) {
89 let checkpoint = self.builder.checkpoint();
90 next(self);
91 while self.peek().map(|t| tokens.contains(&t)).unwrap_or(false) {
92 self.builder.start_node_at(checkpoint, OPERATION.into());
93 self.bump();
94 next(self);
95 self.builder.finish_node();
96 }
97 }
98 fn parse_mul(&mut self) {
99 self.handle_operation(&[MUL, DIV], Self::parse_val)
100 }
101 fn parse_add(&mut self) {
102 self.handle_operation(&[ADD, SUB], Self::parse_mul)
103 }
104 fn parse(mut self) -> SyntaxNode {
105 self.builder.start_node(ROOT.into());
106 self.parse_add();
107 self.builder.finish_node();
108
109 SyntaxNode::new_root(self.builder.finish())
110 }
111 }
112
113 fn print(indent: usize, element: SyntaxElement) {
114 let kind: SyntaxKind = element.kind().into();
115 print!("{:indent$}", "", indent = indent);
116 match element {
117 NodeOrToken::Node(node) => {
118 println!("- {:?}", kind);
119 for child in node.children_with_tokens() {
120 print(indent + 2, child);
121 }
122 }
123
124 NodeOrToken::Token(token) => println!("- {:?} {:?}", token.text(), kind),
125 }
126 }
127
128 fn main() {
129 let ast = Parser {
130 builder: GreenNodeBuilder::new(),
131 iter: vec![
132 // 1 + 2 * 3 + 4
133 (NUMBER, "1".into()),
134 (WHITESPACE, " ".into()),
135 (ADD, "+".into()),
136 (WHITESPACE, " ".into()),
137 (NUMBER, "2".into()),
138 (WHITESPACE, " ".into()),
139 (MUL, "*".into()),
140 (WHITESPACE, " ".into()),
141 (NUMBER, "3".into()),
142 (WHITESPACE, " ".into()),
143 (ADD, "+".into()),
144 (WHITESPACE, " ".into()),
145 (NUMBER, "4".into()),
146 ]
147 .into_iter()
148 .peekable(),
149 }
150 .parse();
151 print(0, ast.into());
152 }