ЛЛ реализации парсера в Русте


Это моя первая попытка в какой-то средней сложности код Руст. К сожалению, он чувствует себя очень неуклюжим для меня, и я чувствую, как будто я не использую все функции должным образом:

use std::collections::HashMap;

fn main() {
    let mut table: Vec<HashMap<&str, Vec<&str>>> = Vec::new();
    table.push(HashMap::new());
    table[0].insert(" ", vec!["F"]);
    table[0].insert("(", vec!["-1"]);
    table[0].insert(")", vec!["-1"]);
    table[0].insert("+", vec!["-1"]);
    table[0].insert("a", vec!["a"]);

    table.push(HashMap::new());
    table[1].insert(" ", vec!["S"]);
    table[1].insert("(", vec!["(", "S", "+", "F", ")"]);
    table[1].insert(")", vec!["-1"]);
    table[1].insert("+", vec!["-1"]);
    table[1].insert("a", vec!["F"]);

    let mut input = vec!["(", "a", "+", "a", ")"];

    parse_func(&mut table, &mut input);
}

fn parse_func(table: &mut Vec<HashMap<&str, Vec<&str>>>, input: &mut Vec<&str>) {
    let mut stack: Vec<&str> = Vec::new();
    stack.push("S");
    for c in input.iter() {
        loop {
            println!("{:?}", stack);
            let rulenum: usize = match *c {
                "$" => return,
                sval if (sval == *stack.last().unwrap()) => {stack.pop(); break;},
                _ => evaluate_table(table, c, vec![stack.last().unwrap()]).expect("Bad input"),
            };
            stack.pop();
            for item in table.get(rulenum).unwrap().get(c).unwrap().iter().rev() {
                stack.push(item);
            }
        }
    }
}

fn evaluate_table(table: &Vec<HashMap<&str, Vec<&str>>>, c: &str, nterminal: Vec<&str>) -> Option<usize> {
    for (i, row) in table.iter().enumerate() {
        if *row.get(" ").unwrap() == nterminal {
            return match row.get(c).unwrap() {
                k if (*k == vec!["-1"]) => None,
                _ => Some(i),
            }
        }
    }
    None
}


152
1
задан 12 февраля 2018 в 02:02 Источник Поделиться
Комментарии