From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/rowan/examples/math.rs | 152 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 vendor/rowan/examples/math.rs (limited to 'vendor/rowan/examples/math.rs') diff --git a/vendor/rowan/examples/math.rs b/vendor/rowan/examples/math.rs new file mode 100644 index 000000000..930c591b0 --- /dev/null +++ b/vendor/rowan/examples/math.rs @@ -0,0 +1,152 @@ +//! Example that takes the input +//! 1 + 2 * 3 + 4 +//! and builds the tree +//! - Marker(Root) +//! - Marker(Operation) +//! - Marker(Operation) +//! - "1" Token(Number) +//! - "+" Token(Add) +//! - Marker(Operation) +//! - "2" Token(Number) +//! - "*" Token(Mul) +//! - "3" Token(Number) +//! - "+" Token(Add) +//! - "4" Token(Number) + +use rowan::{GreenNodeBuilder, NodeOrToken}; +use std::iter::Peekable; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[allow(non_camel_case_types)] +#[repr(u16)] +enum SyntaxKind { + WHITESPACE = 0, + + ADD, + SUB, + MUL, + DIV, + + NUMBER, + ERROR, + OPERATION, + ROOT, +} +use SyntaxKind::*; + +impl From for rowan::SyntaxKind { + fn from(kind: SyntaxKind) -> Self { + Self(kind as u16) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +enum Lang {} +impl rowan::Language for Lang { + type Kind = SyntaxKind; + fn kind_from_raw(raw: rowan::SyntaxKind) -> Self::Kind { + assert!(raw.0 <= ROOT as u16); + unsafe { std::mem::transmute::(raw.0) } + } + fn kind_to_raw(kind: Self::Kind) -> rowan::SyntaxKind { + kind.into() + } +} + +type SyntaxNode = rowan::SyntaxNode; +#[allow(unused)] +type SyntaxToken = rowan::SyntaxToken; +#[allow(unused)] +type SyntaxElement = rowan::NodeOrToken; + +struct Parser> { + builder: GreenNodeBuilder<'static>, + iter: Peekable, +} +impl> Parser { + fn peek(&mut self) -> Option { + while self.iter.peek().map(|&(t, _)| t == WHITESPACE).unwrap_or(false) { + self.bump(); + } + self.iter.peek().map(|&(t, _)| t) + } + fn bump(&mut self) { + if let Some((token, string)) = self.iter.next() { + self.builder.token(token.into(), string.as_str()); + } + } + fn parse_val(&mut self) { + match self.peek() { + Some(NUMBER) => self.bump(), + _ => { + self.builder.start_node(ERROR.into()); + self.bump(); + self.builder.finish_node(); + } + } + } + fn handle_operation(&mut self, tokens: &[SyntaxKind], next: fn(&mut Self)) { + let checkpoint = self.builder.checkpoint(); + next(self); + while self.peek().map(|t| tokens.contains(&t)).unwrap_or(false) { + self.builder.start_node_at(checkpoint, OPERATION.into()); + self.bump(); + next(self); + self.builder.finish_node(); + } + } + fn parse_mul(&mut self) { + self.handle_operation(&[MUL, DIV], Self::parse_val) + } + fn parse_add(&mut self) { + self.handle_operation(&[ADD, SUB], Self::parse_mul) + } + fn parse(mut self) -> SyntaxNode { + self.builder.start_node(ROOT.into()); + self.parse_add(); + self.builder.finish_node(); + + SyntaxNode::new_root(self.builder.finish()) + } +} + +fn print(indent: usize, element: SyntaxElement) { + let kind: SyntaxKind = element.kind().into(); + print!("{:indent$}", "", indent = indent); + match element { + NodeOrToken::Node(node) => { + println!("- {:?}", kind); + for child in node.children_with_tokens() { + print(indent + 2, child); + } + } + + NodeOrToken::Token(token) => println!("- {:?} {:?}", token.text(), kind), + } +} + +fn main() { + let ast = Parser { + builder: GreenNodeBuilder::new(), + iter: vec![ + // 1 + 2 * 3 + 4 + (NUMBER, "1".into()), + (WHITESPACE, " ".into()), + (ADD, "+".into()), + (WHITESPACE, " ".into()), + (NUMBER, "2".into()), + (WHITESPACE, " ".into()), + (MUL, "*".into()), + (WHITESPACE, " ".into()), + (NUMBER, "3".into()), + (WHITESPACE, " ".into()), + (ADD, "+".into()), + (WHITESPACE, " ".into()), + (NUMBER, "4".into()), + ] + .into_iter() + .peekable(), + } + .parse(); + print(0, ast.into()); +} -- cgit v1.2.3