use super::ast::Node;
use super::lexer::Lexer;
use super::token::Token;
use super::types::Type;
pub struct Parser {
current_token: Token,
lexer: Box<Lexer>,
}
impl Parser {
pub fn new(mut lexer: Box<Lexer>) -> Self {
Self {
current_token: lexer.get_next_token(),
lexer: lexer,
}
}
fn program(&mut self) -> Box<Node> {
let node = self.compound_statement();
self.eat(Type::DOT);
return node;
}
fn compound_statement(&mut self) -> Box<Node> {
self.eat(Type::BEGIN);
let nodes = self.statement_list();
self.eat(Type::END);
return Node::compound_op(self.current_token.clone(), nodes);
}
fn statement_list(&mut self) -> Vec<Box<Node>> {
let node = self.statement();
let mut v = Vec::new();
v.push(node);
while *self.current_token.get_type() == Type::SEMI {
self.eat(Type::SEMI);
v.push(self.statement());
}
return v;
}
fn statement(&mut self) -> Box<Node> {
match *self.current_token.get_type() {
Type::BEGIN => {
return self.compound_statement();
}
Type::VARIABLE => {
return self.assignment_statement();
}
_ => return self.empty(),
}
}
fn assignment_statement(&mut self) -> Box<Node> {
let left = self.variable();
let token = self.current_token.clone();
self.eat(Type::ASSIGN);
let right = self.expr();
return Node::assign(token, left, right);
}
fn variable(&mut self) -> Box<Node> {
let node = Node::var(self.current_token.clone());
self.eat(Type::VARIABLE);
return node;
}
fn factor(&mut self) -> Box<Node> {
let token = self.current_token.clone();
match *token.get_type() {
Type::MINUS => {
self.eat(Type::MINUS);
let node = Node::unary_op(token, self.expr());
return node;
}
Type::PLUS => {
self.eat(Type::PLUS);
let node = Node::unary_op(token, self.expr());
return node;
}
Type::LPAREN => {
self.eat(Type::LPAREN);
let node = self.expr();
self.eat(Type::RPAREN);
return node;
}
Type::INTEGER => {
self.eat(Type::INTEGER);
let node = Node::num(token);
return node;
}
_ => {
return self.variable();
}
}
}
fn term(&mut self) -> Box<Node> {
let mut node = self.factor();
while vec![Type::MULTIPLY, Type::DIVIDE].contains(&self.current_token.get_type()) {
let token = self.current_token.clone();
if *token.get_type() == Type::MULTIPLY {
self.eat(Type::MULTIPLY);
}
if *token.get_type() == Type::DIVIDE {
self.eat(Type::DIVIDE);
}
node = Node::bin_op(token, node, self.factor());
}
return node;
}
pub fn expr(&mut self) -> Box<Node> {
let mut node = self.term();
while vec![Type::PLUS, Type::MINUS].contains(&self.current_token.get_type()) {
let token = self.current_token.clone();
if *token.get_type() == Type::PLUS {
self.eat(Type::PLUS);
}
if *token.get_type() == Type::MINUS {
self.eat(Type::MINUS);
}
node = Node::bin_op(token, node, self.term());
}
return node;
}
fn empty(&self) -> Box<Node> {
return Node::no_op();
}
fn eat(&mut self, _type: Type) {
if *self.current_token.get_type() == _type {
self.current_token = self.lexer.get_next_token()
} else {
self.error();
}
}
pub fn parse(&mut self) -> Box<Node> {
return self.program();
}
fn error(&self) {
panic!("Syntax error");
}
}