Skip to content
Snippets Groups Projects
Commit b271d940 authored by Linus Palm's avatar Linus Palm
Browse files

Improved error handling

parent 14e06f87
Branches
1 merge request!1Improved error handling
......@@ -17,13 +17,14 @@ impl<'a> C1Parser<'a> {
println!("Starting parsing");
instance.program().unwrap();
Ok(())
instance.program()
}
fn program(&mut self) -> ParseResult {
self.functiondefinition().unwrap();
while self.lx.current_token().is_some() {
self.functiondefinition()?;
}
Ok(())
}
......@@ -31,16 +32,14 @@ impl<'a> C1Parser<'a> {
if self.lx.current_token() == Some(C1Token::KwInt) || self.lx.current_token() == Some(C1Token::KwVoid) || self.lx.current_token() == Some(C1Token::KwBoolean) || self.lx.current_token() == Some(C1Token::KwFloat) {
self.lx.eat();
self.check_and_eat_token(C1Token::Identifier).unwrap();
self.check_and_eat_token(C1Token::LeftParenthesis).unwrap();
self.check_and_eat_token(C1Token::RightParenthesis).unwrap();
self.check_and_eat_token(C1Token::LeftBrace).unwrap();
self.statementlist().unwrap();
self.check_and_eat_token(C1Token::RightBrace).unwrap();
return Ok(());
self.check_and_eat_token(C1Token::Identifier)?;
self.check_and_eat_token(C1Token::LeftParenthesis)?;
self.check_and_eat_token(C1Token::RightParenthesis)?;
self.check_and_eat_token(C1Token::LeftBrace)?;
self.statementlist()?;
return self.check_and_eat_token(C1Token::RightBrace);
}
return Err(format!("Expected token group 'type' but found {:?}", self.lx.current_token()));
return Err(format!("Expected token group 'type' in line {} but found {:?}", self.lx.current_line_number().unwrap(), self.lx.current_token()));
}
fn statementlist(&mut self) -> ParseResult {
......@@ -73,7 +72,7 @@ impl<'a> C1Parser<'a> {
}*/
while !(self.lx.current_token() == Some(C1Token::RightBrace)) {
self.block().unwrap();
self.block()?;
}
Ok(())
......@@ -82,140 +81,130 @@ impl<'a> C1Parser<'a> {
fn block(&mut self) -> ParseResult {
print!("block->");
if self.lx.current_token() == Some(C1Token::LeftBrace){
self.check_and_eat_token(C1Token::LeftBrace).unwrap();
self.statementlist().unwrap();
self.check_and_eat_token(C1Token::RightBrace).unwrap();
self.check_and_eat_token(C1Token::LeftBrace)?;
self.statementlist()?;
return self.check_and_eat_token(C1Token::RightBrace);
}else{
self.statement().unwrap();
return self.statement();
}
Ok(())
}
fn statement(&mut self) -> ParseResult {
print!("statement->");
match self.lx.current_token() {
Some(C1Token::KwIf) => {
self.ifstatement().unwrap();
Ok(())
return self.ifstatement();
},
Some(C1Token::KwReturn) => {
self.returnstatement().unwrap();
self.check_and_eat_token(C1Token::Semicolon).unwrap();
Ok(())
self.returnstatement()?;
return self.check_and_eat_token(C1Token::Semicolon);
},
Some(C1Token::KwPrintf) => {
self.printfstatement().unwrap();
self.check_and_eat_token(C1Token::Semicolon).unwrap();
Ok(())
self.printfstatement()?;
return self.check_and_eat_token(C1Token::Semicolon);
},
Some(C1Token::Identifier) => {
if self.lx.peek_token() == Some(C1Token::Assign) {
self.statassignment().unwrap();
self.check_and_eat_token(C1Token::Semicolon).unwrap();
self.statassignment()?;
return self.check_and_eat_token(C1Token::Semicolon);
}else{
self.functioncall().unwrap();
self.check_and_eat_token(C1Token::Semicolon).unwrap();
self.functioncall()?;
return self.check_and_eat_token(C1Token::Semicolon);
}
Ok(())
},
_ => Err(format!("Expected token group 'statement' but found {:?}", self.lx.current_token().unwrap())),
_ => Err(format!("Expected token group 'statement' in line {} but found {:?}", self.lx.current_line_number().unwrap(), self.lx.current_token().unwrap())),
}
}
fn functioncall(&mut self) -> ParseResult {
print!("functioncall->");
self.check_and_eat_token(C1Token::Identifier).unwrap();
self.check_and_eat_token(C1Token::LeftParenthesis).unwrap();
self.check_and_eat_token(C1Token::RightParenthesis).unwrap();
Ok(())
self.check_and_eat_token(C1Token::Identifier)?;
self.check_and_eat_token(C1Token::LeftParenthesis)?;
self.check_and_eat_token(C1Token::RightParenthesis)
}
fn statassignment(&mut self) -> ParseResult {
print!("statassignment->");
self.check_and_eat_token(C1Token::Identifier).unwrap();
self.check_and_eat_token(C1Token::Assign).unwrap();
self.assignment().unwrap();
Ok(())
self.check_and_eat_token(C1Token::Identifier)?;
self.check_and_eat_token(C1Token::Assign)?;
self.assignment()
}
fn returnstatement(&mut self) -> ParseResult {
print!("returnstatement->");
self.check_and_eat_token(C1Token::KwReturn).unwrap();
self.assignment(); //TODO: Maybe?
Ok(())
self.check_and_eat_token(C1Token::KwReturn)?;
if self.lx.current_token() == Some(C1Token::Semicolon) {
return Ok(());
}
self.assignment()
}
fn printfstatement(&mut self) -> ParseResult {
print!("printfstatement->");
self.check_and_eat_token(C1Token::KwPrintf).unwrap();
self.check_and_eat_token(C1Token::LeftParenthesis).unwrap();
self.assignment().unwrap();
self.check_and_eat_token(C1Token::RightParenthesis).unwrap();
Ok(())
self.check_and_eat_token(C1Token::KwPrintf)?;
self.check_and_eat_token(C1Token::LeftParenthesis)?;
self.assignment()?;
self.check_and_eat_token(C1Token::RightParenthesis)
}
fn ifstatement(&mut self) -> ParseResult {
print!("ifstatement->");
self.check_and_eat_token(C1Token::KwIf).unwrap();
self.check_and_eat_token(C1Token::LeftParenthesis).unwrap();
self.assignment().unwrap();
//TODO: self.check_and_eat_token(C1Token::RightParenthesis).unwrap();
self.block().unwrap();
Ok(())
self.check_and_eat_token(C1Token::KwIf)?;
self.check_and_eat_token(C1Token::LeftParenthesis)?;
self.assignment()?;
self.check_and_eat_token(C1Token::RightParenthesis)?;
self.block()
}
fn assignment(&mut self) -> ParseResult {
print!("assignment->");
println!("test: {:?} {:?}", self.lx.current_text(), self.lx.peek_text());
if self.lx.current_token() == Some(C1Token::Identifier) && self.lx.peek_token() == Some(C1Token::Assign) {
self.check_and_eat_token(C1Token::Identifier).unwrap();
self.check_and_eat_token(C1Token::Assign).unwrap();
self.assignment().unwrap();
return Ok(());
self.check_and_eat_token(C1Token::Identifier)?;
self.check_and_eat_token(C1Token::Assign)?;
self.assignment()
}else{
println!("assignment: Not Identifier");
self.expr().unwrap();
return Ok(());
self.expr()
}
}
fn expr(&mut self) -> ParseResult {
print!("expr->");
self.simpexpr().unwrap();
self.simpexpr()?;
let tk = self.lx.current_token();
if tk == Some(C1Token::Equal) || tk == Some(C1Token::NotEqual) || tk == Some(C1Token::Less) || tk == Some(C1Token::LessEqual) || tk == Some(C1Token::Greater) || tk == Some(C1Token::GreaterEqual) {
self.lx.eat();
self.simpexpr().unwrap();
}else{
return Ok(());
self.simpexpr()?;
}
self.check_and_eat_token(C1Token::RightParenthesis).unwrap();
Ok(())
}
fn simpexpr(&mut self) -> ParseResult {
print!("simpexpr->");
if self.lx.current_token() == Some(C1Token::Minus){
self.check_and_eat_token(C1Token::Minus).unwrap();
self.check_and_eat_token(C1Token::Minus)?;
}
self.term().unwrap();
self.term()?;
while self.lx.current_token() == Some(C1Token::Plus) || self.lx.current_token() == Some(C1Token::Minus) || self.lx.current_token() == Some(C1Token::Or) {
self.lx.eat();
self.term().unwrap();
self.term()?;
}
Ok(())
}
fn term(&mut self) -> ParseResult {
print!("term->");
self.factor().unwrap();
self.factor()?;
while self.lx.current_token() == Some(C1Token::Asterisk) || self.lx.current_token() == Some(C1Token::Slash) || self.lx.current_token() == Some(C1Token::And) {
self.lx.eat();
self.factor().unwrap();
self.factor()?;
}
Ok(())
}
......@@ -227,37 +216,32 @@ impl<'a> C1Parser<'a> {
match self.lx.current_token() {
Some(C1Token::ConstInt) => {
self.check_and_eat_token(C1Token::ConstInt).unwrap();
Ok(())
self.check_and_eat_token(C1Token::ConstInt)
},
Some(C1Token::ConstFloat) => {
self.check_and_eat_token(C1Token::ConstFloat).unwrap();
Ok(())
self.check_and_eat_token(C1Token::ConstFloat)
},
Some(C1Token::ConstBoolean) => {
self.check_and_eat_token(C1Token::ConstBoolean).unwrap();
Ok(())
self.check_and_eat_token(C1Token::ConstBoolean)
},
Some(C1Token::Identifier) => {
if self.lx.peek_token() == Some(C1Token::LeftParenthesis) {
self.functioncall().unwrap();
return self.functioncall();
}else{
self.check_and_eat_token(C1Token::Identifier).unwrap();
return self.check_and_eat_token(C1Token::Identifier);
}
Ok(())
},
Some(C1Token::LeftParenthesis) => {
print!("factor left parenthesis->");
self.check_and_eat_token(C1Token::LeftParenthesis).unwrap();
self.assignment().unwrap();
self.check_and_eat_token(C1Token::RightParenthesis).unwrap();
self.check_and_eat_token(C1Token::LeftParenthesis)?;
self.assignment()?;
self.check_and_eat_token(C1Token::RightParenthesis)?;
Ok(())
},
_ => Err(format!("Expected token group 'factor' but found {:?}", self.lx.current_token().unwrap())),
_ => Err(format!("Expected token group 'factor' in line {} but found {:?}", self.lx.current_line_number().unwrap(), self.lx.current_token().unwrap())),
}
}
......@@ -267,7 +251,7 @@ impl<'a> C1Parser<'a> {
if self.lx.current_token() == Some(token) {
Ok(())
} else {
Err(format!("Expected token {:?}", token))
Err(format!("Expected token {:?} in line {}", token, self.lx.current_line_number().unwrap()))
}
}
......@@ -281,7 +265,7 @@ impl<'a> C1Parser<'a> {
return Ok(());
}
println!("Wrong: {:?}", x);
return Err(format!("Expected token {:?} but found {:?}", token, x));
return Err(format!("Expected token {:?} in line {} but found {:?}", token, self.lx.current_line_number().unwrap(), x));
},
None => Err("No token".to_owned()),
}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment