diff --git a/src/parser.rs b/src/parser.rs index 734af39..31e605e 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,12 +1,498 @@ -use std::{slice::Iter, iter::{Peekable, Map}, collections::HashMap}; - use crate::tokenizer::Token; -use crate::grammar::{NONTERMINAL_NAMES, Rule, NONTERMINAL_RULES, TERMINAL_RULES}; +use crate::grammar::{NONTERMINAL_NAMES, NONTERMINAL_RULES, TERMINAL_RULES}; +pub fn parse(tokens: Vec) -> Result +{ + return own(tokens); +} + +fn own(tokens: Vec) -> Result +{ + return parse_chunk(&tokens, &mut 0); +} + +#[derive(Debug)] +pub struct ChunkNode +{ + block: BlockNode +} +#[derive(Debug)] +pub struct BlockNode +{ + stats: Vec, + retstat: Option +} +#[derive(Debug)] +pub enum StatNode +{ + Semicolon, + Assignment { lhs: VarlistNode, rhs: ExplistNode }, + Functioncall(FunctioncallNode), + Label(String), + Break, + Goto(String), + Do(BlockNode), + While { condition: ExpNode, body: BlockNode }, + Repeat { condition: ExpNode, body: BlockNode }, + If { condition: ExpNode, body: BlockNode, elseifs: Vec, else_: Option }, + ForEq { var: String, start: ExpNode, end: ExpNode, change: Option, body: BlockNode }, + ForIn { vars: Vec, exps: ExplistNode, body: BlockNode }, + Function { name: FuncnameNode, body: FuncbodyNode }, + LocalFunction { name: String, body: FuncbodyNode }, + Local { attnames: AttnamelistNode, values: Option } +} +#[derive(Debug)] +pub struct RetstatNode +{ + values: ExplistNode +} +#[derive(Debug)] +pub struct ExpNode +{ + +} +#[derive(Debug)] +pub struct ExplistNode +{ + exps: Vec +} +#[derive(Debug)] +pub struct VarlistNode +{ + vars: Vec +} +#[derive(Debug)] +pub struct FunctioncallNode +{ + function: SuffixexpNode, + object_arg: Option, + args: ArgsNode, +} +#[derive(Debug)] +pub struct ArgsNode +{ + +} +#[derive(Debug)] +pub struct ElseifNode +{ + condition: ExpNode, + body: BlockNode, +} +#[derive(Debug)] +pub struct FuncnameNode +{ + +}#[derive(Debug)] +pub struct FuncbodyNode +{ + +} +#[derive(Debug)] +pub struct AttnamelistNode +{ + +} +#[derive(Debug)] +pub enum VarNode +{ + Name(String), + Indexed { value: PrefixexpNode, index: ExpNode }, + Member { value: PrefixexpNode, name: String } +} +#[derive(Debug)] +pub enum PrefixexpNode +{ + +} +fn parse_chunk(tokens: &Vec, i: &mut usize) -> Result +{ + return Ok(ChunkNode { block: parse_block(tokens, i)? }); +} +fn parse_block(tokens: &Vec, i: &mut usize) -> Result +{ + let mut stats: Vec = Vec::new(); + while *i < tokens.len() && tokens[*i] != Token::Return + { + stats.push(parse_stat(tokens, i)?); + } + let retstat = + if *i < tokens.len() && tokens[*i] == Token::Return { Some(parse_retstat(tokens, i)?) } + else { None }; + return Ok(BlockNode { stats, retstat }); +} +fn parse_stat(tokens: &Vec, i: &mut usize) -> Result +{ + if *i >= tokens.len() + { + return Err("Reached end of file while parsing stat"); + } + match tokens[*i] + { + Token::Semicolon => + { + *i += 1; + Ok(StatNode::Semicolon) + } + Token::Break => + { + *i += 1; + Ok(StatNode::Break) + } + Token::Goto => + { + *i += 1; + if *i >= tokens.len() + { + return Err("Reached end of stream but expected name for goto"); + } + return if let Token::Name(name) = &tokens[*i] + { + *i += 1; + Ok(StatNode::Goto(name.clone())) + } + else + { + Err("Expecting name for goto") + }; + } + Token::Do => + { + *i += 1; + let body = parse_block(tokens, i)?; + if *i >= tokens.len() || tokens[*i] != Token::End + { + return Err("Missing 'end' for do block"); + } + *i += 1; + return Ok(StatNode::Do(body)); + } + Token::While => + { + *i += 1; + let condition = parse_exp(tokens, i)?; + if *i >= tokens.len() || tokens[*i] != Token::Do + { + return Err("Expected 'do' after while condition") + } + *i += 1; + let body = parse_block(tokens, i)?; + if *i >= tokens.len() || tokens[*i] != Token::End + { + return Err("Missing 'end' for do block"); + } + *i += 1; + return Ok(StatNode::While { condition, body }); + } + Token::Repeat => + { + *i += 1; + let body = parse_block(tokens, i)?; + if *i >= tokens.len() || tokens[*i] != Token::Until + { + return Err("Expected 'until' after repeat body"); + } + *i += 1; + return Ok(StatNode::Repeat { condition: parse_exp(tokens, i)?, body }); + } + Token::If => + { + *i += 1; + let condition = parse_exp(tokens, i)?; + if *i >= tokens.len() || tokens[*i] != Token::Then + { + return Err("Expected 'then' after if condition"); + } + *i += 1; + let body = parse_block(tokens, i)?; + if *i >= tokens.len() + { + return Err("Reached end of tokens while parsing if"); + } + let mut elseifs: Vec = Vec::new(); + while tokens[*i] == Token::Elseif + { + *i += 1; + let elseif_condition = parse_exp(tokens, i)?; + if *i >= tokens.len() || tokens[*i] != Token::Then + { + return Err("Expected 'then' after elseif condition"); + } + *i += 1; + elseifs.push(ElseifNode { condition: elseif_condition, body: parse_block(tokens, i)? }); + } + if *i >= tokens.len() + { + return Err("Reached end of tokens while parsing if"); + } + let else_ = if tokens[*i] == Token::Else + { + *i += 1; + Some(parse_block(tokens, i)?) + } + else + { + None + }; + if *i >= tokens.len() || tokens[*i] != Token::End + { + return Err("Expected 'end' to close if"); + } + *i += 1; + return Ok(StatNode::If { condition, body, elseifs, else_ }); + } + Token::For => + { + *i += 1; + if *i >= tokens.len() + { + return Err("Reached end of tokens while parsing for"); + } + if let Token::Name(name) = &tokens[*i] + { + *i += 1; + if *i >= tokens.len() + { + return Err("Reached end of tokens while parsing for after first name"); + } + match tokens[*i] + { + Token::Equals => + { + *i += 1; + let start = parse_exp(tokens, i)?; + if *i >= tokens.len() || tokens[*i] != Token::Comma + { + return Err("Expected ',' after 'for eq' start value"); + } + *i += 1; + let end = parse_exp(tokens, i)?; + if *i >= tokens.len() + { + return Err("Reached end of tokens after end value in 'for eq'"); + } + let change = if tokens[*i] == Token::Comma + { + *i += 1; + Some(parse_exp(tokens, i)?) + } + else + { + None + }; + if *i >= tokens.len() || tokens[*i] != Token::Do + { + return Err("Expected 'do' after 'for eq' head"); + } + *i += 1; + let body = parse_block(tokens, i)?; + if *i >= tokens.len() || tokens[*i] != Token::End + { + return Err("Expected 'end' to close 'for eq'"); + } + return Ok(StatNode::ForEq { var: name.clone(), start, end, change, body }); + } + Token::Comma => + { + let mut names = Vec::from([name.clone()]); + while tokens[*i] == Token::Comma + { + *i += 1; + if *i >= tokens.len() + { + return Err("Reached end of tokens while parsing 'for in' namelist"); + } + if let Token::Name(next_name) = &tokens[*i] + { + names.push(next_name.clone()); + } + else + { + return Err("Expected another name in 'for in' namelist"); + } + *i += 1; + if *i >= tokens.len() + { + return Err("Reached end of tokens while parsing 'for in' namelist after name"); + } + } + if tokens[*i] != Token::In + { + return Err("Expected 'in' after 'for in' namelist"); + } + *i += 1; + let exps = parse_explist(tokens, i)?; + if *i >= tokens.len() || tokens[*i] != Token::Do + { + return Err("Expected 'do' after 'for in' explist"); + } + *i += 1; + let body = parse_block(tokens, i)?; + if *i >= tokens.len() || tokens[*i] != Token::End + { + return Err("Expected 'end' after 'for in' body"); + } + *i += 1; + return Ok(StatNode::ForIn { vars: names, exps, body }); + } + _ => Err("Unexpected token after first name in for") + } + } + else + { + return Err("Expected name after 'for'"); + } + } + Token::Function => + { + *i += 1; + let funcname = parse_funcname(tokens, i)?; + return Ok(StatNode::Function { name: funcname, body: parse_funcbody(tokens, i)? }); + } + Token::Local => + { + *i += 1; + if *i >= tokens.len() + { + return Err("Reached end of tokens while parsing local"); + } + if tokens[*i] == Token::Function + { + *i += 1; + if *i >= tokens.len() + { + return Err("Reached end of tokens while parsing local function"); + } + if let Token::Name(name) = &tokens[*i] + { + *i += 1; + return Ok(StatNode::LocalFunction { name: name.clone(), body: parse_funcbody(tokens, i)? }); + } + else + { + return Err("Expected local function name"); + } + } + let attnames = parse_attnamelist(tokens, i)?; + let initials = if *i < tokens.len() && tokens[*i] == Token::Equals + { + *i += 1; + Some(parse_explist(tokens, i)?) + } + else + { + None + }; + return Ok(StatNode::Local { attnames, values: initials }); + } + Token::ColonColon => + { + *i += 1; + if *i >= tokens.len() + { + return Err("Reached end of tokens while parsing label"); + } + if let Token::Name(name) = &tokens[*i] + { + *i += 1; + if *i >= tokens.len() || tokens[*i] != Token::ColonColon + { + return Err("Expected '::' after name in label declaration"); + } + *i += 1; + return Ok(StatNode::Label(name.clone())); + } + else + { + return Err("Expected a name after '::' in label declaration") + } + } + Token::Name(_) | Token::RoundOpen => + { + // assignment or functioncall + let suffix_expression = parse_suffixexp(tokens, i)?; + match tokens[*i] + { + Token::Equals => + { + *i += 1; + return Ok(StatNode::Assignment { lhs: VarlistNode { vars: Vec::from([suffix_expression_to_var(suffix_expression)]) }, rhs: parse_explist(tokens, i)? }); + } + Token::Comma => + { + let mut vars = Vec::from([suffix_expression_to_var(suffix_expression)]); + while tokens[*i] == Token::Comma + { + *i += 1; + vars.push(parse_var(tokens, i)?); + } + if *i >= tokens.len() || tokens[*i] != Token::Equals + { + return Err("Expected '=' for assignment"); + } + *i += 1; + return Ok(StatNode::Assignment { lhs: VarlistNode { vars }, rhs: parse_explist(tokens, i)? }); + } + _ => + { + if let SuffixexpNode() + } + } + } + _ => Err("Unexpected token while parsing stat") + } +} +fn suffix_expression_to_var(suffixexp: SuffixexpNode) -> VarNode +{ + todo!() +} +fn parse_var(tokens: &Vec, i: &mut usize) -> Result +{ + todo!() +} +fn parse_args(tokens: &Vec, i: &mut usize) -> Result +{ + todo!() +} +fn parse_suffixexp(tokens: &Vec, i: &mut usize) -> Result +{ + // primaryexp { '.' 'Name' | '[' exp']' | ':' 'Name' args | args } + todo!() +} +fn parse_retstat(tokens: &Vec, i: &mut usize) -> Result +{ + todo!("{:?}", tokens[*i]) +} +fn parse_exp(tokens: &Vec, i: &mut usize) -> Result +{ + todo!("{:?}", tokens[*i]) +} +fn parse_explist(tokens: &Vec, i: &mut usize) -> Result +{ + todo!("{:?}", tokens[*i]) +} +fn parse_funcname(tokens: &Vec, i: &mut usize) -> Result +{ + todo!("{:?}", tokens[*i]) +} +fn parse_funcbody(tokens: &Vec, i: &mut usize) -> Result +{ + todo!("{:?}", tokens[*i]) +} +fn parse_attnamelist(tokens: &Vec, i: &mut usize) -> Result +{ + todo!("{:?}", tokens[*i]) +} +//=============================================================================================================================================== +//=============================================================================================================================================== +//=============================================================================================================================================== +//=============================================================================================================================================== +//=============================================================================================================================================== +//=============================================================================================================================================== #[derive(Debug, Clone, Copy)] pub struct Node { - + } #[derive(Debug, Clone, Copy)] @@ -14,13 +500,7 @@ pub struct AmbiguousNode { } - -pub fn parse(tokens: Vec) -> Result -{ - return cyk(tokens); -} - -pub fn cyk(tokens: Vec) -> Result +pub fn cyk(tokens: Vec) -> Result { let r = NONTERMINAL_NAMES.len(); let n = tokens.len(); @@ -108,4 +588,4 @@ fn traverse_back(back: Vec>, tokens: Vec, l: usize, fn disambiguate(root: AmbiguousNode) -> Node { todo!() -} \ No newline at end of file +}