111 lines
2.2 KiB
Rust
111 lines
2.2 KiB
Rust
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<Token>) -> Result<Node, &'static str>
|
|
{
|
|
return cyk(tokens);
|
|
}
|
|
|
|
pub fn cyk(tokens: Vec<Token>) -> Result<Node, &'static str>
|
|
{
|
|
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<(usize, u8, u8)>> = 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<Vec<(usize, u8, u8)>>, tokens: Vec<Token>, l: usize, s: usize, a: usize) -> AmbiguousNode
|
|
{
|
|
todo!()
|
|
}
|
|
|
|
fn disambiguate(root: AmbiguousNode) -> Node
|
|
{
|
|
todo!()
|
|
} |