use std::{slice::Iter, iter::{Peekable, Map}, collections::HashMap}; use crate::tokenizer::Token; use crate::grammar::{NONTERMINAL_NAMES, Rule, NONTERMINAL_RULES, TERMINAL_RULES}; #[derive(Debug, Clone, Copy)] pub struct Node { } #[derive(Debug, Clone, Copy)] pub struct AmbiguousNode { } pub fn parse(tokens: Vec) -> Result { return cyk(tokens); } pub fn cyk(tokens: Vec) -> Result { let r = NONTERMINAL_NAMES.len(); let n = tokens.len(); macro_rules! index { ($x:expr, $y:expr, $z:expr) => { ($x + $y * n + ($z as usize) * n * n) }; } let mut p = vec![false; n * n * r]; //let mut back: Vec> = vec![Vec::new(); n * n * r]; println!("{n}, {r}, {}", p.len()); for s in 0..n { for (index, token) in TERMINAL_RULES { if let Token::Name(_) = tokens[s] { if let Token::Name(_) = token { p[index!(0, s, index)] = true } } else if let Token::StringLiteral(_) = tokens[s] { if let Token::StringLiteral(_) = token { p[index!(0, s, index)] = true } } else if let Token::Numeral(_) = tokens[s] { if let Token::Numeral(_) = token { p[index!(0, s, index)] = true } } else if token == tokens[s] { p[index!(0, s, index)] = true } } } println!("Done initializing"); for l in 2..=n { for s in 1..=(n - l + 1) { for _p in 1..=(l-1) { for &(a, b, c) in &NONTERMINAL_RULES { if p[index!(_p - 1, s - 1, b)] && p[index!(l - _p - 1, s + _p - 1, c)] { let index = index!(l - 1, s - 1, a); p[index] = true; /* if !back[index].contains(&(_p, b, c)) { back[index].push((_p, b, c)); }*/ } } } } println!("{l}"); } let start_index = NONTERMINAL_NAMES.iter().position(|x| x == &"S_0").expect("no start index found"); if p[index!(n - 1, 0, start_index)] { println!("Is part of the language"); todo!() //return Ok(disambiguate(traverse_back(back, tokens, n, 1, start_index))); } else { return Err("Input is not part of the language") } } fn traverse_back(back: Vec>, tokens: Vec, l: usize, s: usize, a: usize) -> AmbiguousNode { todo!() } fn disambiguate(root: AmbiguousNode) -> Node { todo!() }