Add terribly slow cyk parser
This commit is contained in:
347
src/parser.rs
347
src/parser.rs
@ -1,290 +1,111 @@
|
||||
use std::slice::Iter;
|
||||
use std::{slice::Iter, iter::{Peekable, Map}, collections::HashMap};
|
||||
|
||||
use crate::tokenizer::Token;
|
||||
#[derive(Debug)]
|
||||
pub struct BlockNode
|
||||
{
|
||||
stats: Vec<StatNode>,
|
||||
retstat: Option<RetstatNode>
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub enum StatNode
|
||||
{
|
||||
Semicolon,
|
||||
Assignment(AssignmentNode),
|
||||
FunctionCall(FunctionCallNode),
|
||||
Label(LabelNode),
|
||||
Break,
|
||||
Goto(GotoNode),
|
||||
Block(BlockNode),
|
||||
While(WhileNode),
|
||||
Repeat(RepeatNode),
|
||||
If(IfNode),
|
||||
For(ForNode),
|
||||
ForIn(ForInNode),
|
||||
Function(FunctionNode),
|
||||
LocalFunction(LocalFunctionNode),
|
||||
Local(LocalNode),
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct AssignmentNode
|
||||
{
|
||||
use crate::grammar::{NONTERMINAL_NAMES, Rule, NONTERMINAL_RULES, TERMINAL_RULES};
|
||||
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct FunctionCallNode
|
||||
{
|
||||
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct RetstatNode
|
||||
{
|
||||
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct LabelNode
|
||||
{
|
||||
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct GotoNode
|
||||
{
|
||||
label: String
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct WhileNode
|
||||
{
|
||||
condition: ExpNode,
|
||||
block: BlockNode,
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct RepeatNode
|
||||
{
|
||||
condition: ExpNode,
|
||||
block: BlockNode,
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct IfNode
|
||||
{
|
||||
condition: ExpNode,
|
||||
then_block: BlockNode,
|
||||
elseifs: Option<Vec<ElseIfNode>>
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct ElseIfNode
|
||||
{
|
||||
condition: ExpNode,
|
||||
block: BlockNode,
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct ForNode
|
||||
{
|
||||
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct ForInNode
|
||||
{
|
||||
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct FunctionNode
|
||||
{
|
||||
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct LocalFunctionNode
|
||||
{
|
||||
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct LocalNode
|
||||
{
|
||||
|
||||
}
|
||||
#[derive(Debug)]
|
||||
pub struct ExpNode
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Node
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pub fn parse(tokens: Vec<Token>) -> Result<BlockNode, &'static str>
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct AmbiguousNode
|
||||
{
|
||||
let mut iter = tokens.iter();
|
||||
return parse_block(&mut iter);
|
||||
|
||||
}
|
||||
|
||||
fn parse_block(tokens: &mut Iter<'_, Token>) -> Result<BlockNode, &'static str>
|
||||
pub fn parse(tokens: Vec<Token>) -> Result<Node, &'static str>
|
||||
{
|
||||
let mut block_node = BlockNode { retstat: None, stats: Vec::new() };
|
||||
while let Some(stat) = parse_stat(tokens)?
|
||||
{
|
||||
block_node.stats.push(stat);
|
||||
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)
|
||||
};
|
||||
}
|
||||
block_node.retstat = parse_retstat(tokens)?;
|
||||
return Ok(block_node);
|
||||
}
|
||||
|
||||
fn parse_stat(tokens: &mut Iter<'_, Token>) -> Result<Option<StatNode>, &'static str>
|
||||
{
|
||||
match tokens.next()
|
||||
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
|
||||
{
|
||||
Some(token) =>
|
||||
for (index, token) in TERMINAL_RULES
|
||||
{
|
||||
match token
|
||||
if let Token::Name(_) = tokens[s]
|
||||
{
|
||||
Token::Semicolon => return Ok(Some(StatNode::Semicolon)),
|
||||
Token::Break => return Ok(Some(StatNode::Break)),
|
||||
Token::Goto =>
|
||||
if let Token::Name(_) = token
|
||||
{
|
||||
match tokens.next()
|
||||
{
|
||||
Some(Token::Name(string)) => return Ok(Some(StatNode::Goto(GotoNode { label: string.clone() }))),
|
||||
_ => return Err("Failed to parse goto statement")
|
||||
}
|
||||
}
|
||||
Token::Do =>
|
||||
p[index!(0, s, index)] = true
|
||||
}
|
||||
}
|
||||
else if let Token::StringLiteral(_) = tokens[s]
|
||||
{
|
||||
if let Token::StringLiteral(_) = token
|
||||
{
|
||||
let block = parse_block(tokens)?;
|
||||
match tokens.next()
|
||||
{
|
||||
Some(Token::End) => return Ok(Some(StatNode::Block(block))),
|
||||
_ => return Err("Failed to parse block statement")
|
||||
}
|
||||
}
|
||||
Token::While =>
|
||||
p[index!(0, s, index)] = true
|
||||
}
|
||||
}
|
||||
else if let Token::Numeral(_) = tokens[s]
|
||||
{
|
||||
if let Token::Numeral(_) = token
|
||||
{
|
||||
if let Some(condition) = parse_exp(tokens)?
|
||||
{
|
||||
match tokens.next()
|
||||
{
|
||||
Some(Token::Do) =>
|
||||
{
|
||||
let block = parse_block(tokens)?;
|
||||
match tokens.next()
|
||||
{
|
||||
Some(Token::End) => return Ok(Some(StatNode::While(WhileNode { condition, block }))),
|
||||
_ => Err("No end after while block")
|
||||
}
|
||||
}
|
||||
_ => Err("No do after while condition"),
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Err("Failed to parse while condition");
|
||||
}
|
||||
}
|
||||
Token::Repeat =>
|
||||
{
|
||||
let block = parse_block(tokens)?;
|
||||
match tokens.next()
|
||||
{
|
||||
Some(Token::Until) =>
|
||||
{
|
||||
match parse_exp(tokens)?
|
||||
{
|
||||
Some(exp) => return Ok(Some(StatNode::Repeat(RepeatNode { condition: exp, block }))),
|
||||
None => Err("Failed to parse repeat condition")
|
||||
}
|
||||
}
|
||||
_ => Err("Missing until after repeat block")
|
||||
}
|
||||
}
|
||||
Token::If =>
|
||||
{
|
||||
if let Some(condition) = parse_exp(tokens)?
|
||||
{
|
||||
match tokens.next()
|
||||
{
|
||||
Some(Token::Then) =>
|
||||
{
|
||||
let block = parse_block(tokens)?;
|
||||
let mut elseifs: Vec<ElseIfNode> = Vec::new();
|
||||
loop
|
||||
{
|
||||
match tokens.next()
|
||||
{
|
||||
Some(Token::Elseif) =>
|
||||
{
|
||||
if let Some(elseif_condition) = parse_exp(tokens)?
|
||||
{
|
||||
match tokens.next()
|
||||
{
|
||||
Some(Token::Then) =>
|
||||
{
|
||||
elseifs.push(ElseIfNode { block: parse_block(tokens)?, condition: elseif_condition });
|
||||
}
|
||||
_ => return Err("Missing Then after elseif statement"),
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Err("Failed to parse elseif condition");
|
||||
}
|
||||
}
|
||||
Some(Token::Else) =>
|
||||
{
|
||||
match tokens.next()
|
||||
{
|
||||
Some(Token::End) => return Ok(Some(StatNode::If(IfNode { condition, then_block: block, elseifs: Some(elseifs) }))),
|
||||
_ => return Err("Missing end after else")
|
||||
}
|
||||
}
|
||||
Some(Token::End) =>
|
||||
{
|
||||
return Ok(Some(StatNode::If(IfNode { condition, then_block: block, elseifs: None })));
|
||||
}
|
||||
_ => return Err("Missing end after if block")
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => return Err("Missing then after if condition")
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Err("Failed to parse if condition");
|
||||
}
|
||||
}
|
||||
Token::For =>
|
||||
{
|
||||
match tokens.next()
|
||||
{
|
||||
Some(Token::Name(name)) =>
|
||||
{
|
||||
match tokens.next()
|
||||
{
|
||||
Some(Token::Equals) =>
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
_ => todo!()
|
||||
}
|
||||
}
|
||||
_ => Err("Missing name after for"),
|
||||
}
|
||||
}
|
||||
_ => todo!()
|
||||
p[index!(0, s, index)] = true
|
||||
}
|
||||
}
|
||||
else if token == tokens[s]
|
||||
{
|
||||
p[index!(0, s, index)] = true
|
||||
}
|
||||
}
|
||||
None => return Ok(None),
|
||||
}
|
||||
}
|
||||
println!("Done initializing");
|
||||
|
||||
fn parse_exp(tokens: &mut Iter<'_, Token>) -> Result<Option<ExpNode>, &'static str>
|
||||
{
|
||||
todo!();
|
||||
}
|
||||
|
||||
fn parse_retstat(tokens: &mut Iter<'_, Token>) -> Result<Option<RetstatNode>, &'static str>
|
||||
{
|
||||
match tokens.next()
|
||||
for l in 2..=n
|
||||
{
|
||||
Some(Token::Return) =>
|
||||
for s in 1..=(n - l + 1)
|
||||
{
|
||||
todo!()
|
||||
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));
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None => return Ok(None),
|
||||
_ => return Err("Found wrong token at the beginning of retstat")
|
||||
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!()
|
||||
}
|
Reference in New Issue
Block a user