begin parser
This commit is contained in:
parent
054c8d2fb7
commit
6aa40a3e3e
4 changed files with 132 additions and 3 deletions
91
src/parser.rs
Normal file
91
src/parser.rs
Normal file
|
@ -0,0 +1,91 @@
|
|||
use crate::lexer::{Token, TokenType};
|
||||
|
||||
pub enum ASTPart {
|
||||
Number(AstNumber),
|
||||
Assigment(AstAssigment),
|
||||
Operation(AstOperation),
|
||||
VarRead(AstVarRead),
|
||||
NOOP
|
||||
}
|
||||
pub struct AstNumber {
|
||||
pub value: i64,
|
||||
pub pos: usize
|
||||
}
|
||||
pub struct AstAssigment {
|
||||
pub variable: String,
|
||||
pub value: Box<ASTPart>,
|
||||
pub pos: usize
|
||||
}
|
||||
pub struct AstOperation {
|
||||
pub operator: String,
|
||||
pub left: Box<ASTPart>,
|
||||
pub right: Box<ASTPart>,
|
||||
pub pos: usize
|
||||
}
|
||||
pub struct AstVarRead {
|
||||
pub variable: String,
|
||||
pub pos: usize
|
||||
}
|
||||
|
||||
|
||||
fn is_end(input: &Token, end: &Vec<Token>) -> bool {
|
||||
for token in end {
|
||||
if input.typ == token.typ && (token.value == "" || input.value == token.value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
fn next_operation(pos: &mut usize, input: &Vec<Token>, prev: ASTPart, op_ends: &Vec<Token>, parse_ends: &Vec<Token>) -> ASTPart {
|
||||
let token = &input[*pos];
|
||||
if is_end(token, &parse_ends) {
|
||||
return prev;
|
||||
}
|
||||
*pos += 1;
|
||||
if is_end(token, &op_ends) {
|
||||
return prev;
|
||||
}
|
||||
if token.typ == TokenType::KEYWORD && token.value == "gethelj" {
|
||||
let variable = &input[*pos];
|
||||
*pos += 1;
|
||||
if variable.typ != TokenType::IDENTIFIER {
|
||||
panic!("Unexpected {:?} at {}", variable.typ, variable.pos)
|
||||
}
|
||||
let eq = &input[*pos];
|
||||
if eq.typ == TokenType::SEPARATOR && eq.value == "=" {
|
||||
*pos += 1;
|
||||
}
|
||||
let value = next_operation(pos, input, ASTPart::NOOP, op_ends, parse_ends);
|
||||
return ASTPart::Assigment(AstAssigment { variable: variable.value.clone(), value: Box::new(value), pos: token.pos });
|
||||
} else if token.typ == TokenType::NUMBER {
|
||||
return next_operation(pos, input, ASTPart::Number(AstNumber { value: token.value.parse().unwrap(), pos: token.pos }), op_ends, parse_ends);
|
||||
} else if token.typ == TokenType::IDENTIFIER {
|
||||
return next_operation(pos, input, ASTPart::VarRead(AstVarRead { variable: token.value.clone(), pos: token.pos }), op_ends, parse_ends);
|
||||
} else {
|
||||
panic!("Unexpected {:?} at {}", token.typ, token.pos);
|
||||
}
|
||||
}
|
||||
fn parse_internal(input: Vec<Token>, op_ends: Vec<Token>, parse_ends: Vec<Token>) -> Vec<ASTPart> {
|
||||
let mut out: Vec<ASTPart> = vec![];
|
||||
let mut pos = 0;
|
||||
while pos < input.len() {
|
||||
let op = next_operation(&mut pos, &input, ASTPart::NOOP, &op_ends, &parse_ends);
|
||||
out.push(op);
|
||||
if is_end(&input[pos], &parse_ends) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
pub fn parse(input: Vec<Token>) -> Vec<ASTPart> {
|
||||
let op_ends: Vec<Token> = vec![
|
||||
Token { typ: TokenType::OPEND, value: String::from("\n"), pos: 0 },
|
||||
Token { typ: TokenType::OPEND, value: String::from(";"), pos: 0 },
|
||||
Token { typ: TokenType::OPEND, value: String::from("EOF"), pos: 0 }
|
||||
];
|
||||
let parse_ends: Vec<Token> = vec![
|
||||
Token { typ: TokenType::OPEND, value: String::from("EOF"), pos: 0 }
|
||||
];
|
||||
let out = parse_internal(input, op_ends, parse_ends);
|
||||
return out;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue