Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::cmp::Ordering;
- #[derive(Debug)]
- struct Node {
- name: String,
- children: Vec<Node>,
- }
- impl Node {
- fn new(name: &str) -> Node {
- Node {
- name: name.to_string(),
- children: Vec::new(),
- }
- }
- }
- #[derive(Debug)]
- pub enum Token {
- Indent,
- Dedent,
- Node(String),
- }
- const TEST_STRING:&str=r#"alpha
- beta
- gamma
- delta
- epsilon
- theta
- iota
- kappa"#;
- fn parse(input: &str) -> Node {
- //lex
- let lines = input.split("\n");
- let mut indent_stack = vec![0];
- let mut tokens = Vec::new();
- for s in lines {
- let indent = s.chars().take_while(|c| *c == ' ').count();
- match indent.cmp(indent_stack.last().unwrap()) {
- Ordering::Equal => {
- // do nothing
- },
- Ordering::Greater => {
- indent_stack.push(indent);
- tokens.push(Token::Indent);
- },
- Ordering::Less => {
- while indent_stack.pop().unwrap() > indent {
- tokens.push(Token::Dedent);
- }
- }
- }
- if s.trim() == "" {
- continue;
- }
- tokens.push(Token::Node(s.trim().to_string()));
- }
- fn parse_node(tokens: &[Token]) -> Result<(&[Token], Node), ()> {
- let mut new_node;
- if let Some(Token::Node(ref name_ref)) = tokens.get(0) {
- new_node = Node::new(name_ref);
- } else { // not headed by `Token::Node`
- return Err(())
- }
- // advance
- let tokens = &tokens[1..];
- if let Some(Token::Indent) = tokens.get(0) {
- // children
- let mut tokens = &tokens[1..];
- while let Ok((remainder, child)) = parse_node(tokens) {
- tokens = remainder;
- new_node.children.push(child);
- }
- return match tokens.get(0) {
- Some(Token::Dedent) => Ok((&tokens[1..], new_node)),
- None => Ok((tokens, new_node)),
- _ => Err(())
- }
- }
- Ok((tokens, new_node))
- }
- parse_node(&tokens).unwrap().1
- /*
- // parse
- let mut indent_level = 0;
- let mut root_node = Node::new("<root>");
- let mut node_ref_stack: Vec<&mut Node> = Vec::new();
- node_ref_stack.push(&mut root_node);
- for token in &tokens {
- match token {
- Token::Indent => {
- let new_indent = indent_level + 1;
- node_ref_stack.push(node_ref_stack.last_mut().unwrap().children.last_mut().unwrap());
- indent_level = new_indent;
- },
- Token::Dedent => {
- indent_level = indent_level - 1;
- },
- Token::Node(name) => {
- &mut node_ref_stack.last_mut().unwrap().children.push(Node::new(name));
- },
- }
- }
- root_node
- */
- }
- fn main() {
- let tree = parse(TEST_STRING);
- println!("{:#?}", tree);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement