Remove parse mod
This commit is contained in:
parent
2e619e716f
commit
cc1a87761d
3 changed files with 0 additions and 209 deletions
|
|
@ -1,5 +1,4 @@
|
||||||
mod lexer;
|
mod lexer;
|
||||||
mod parser;
|
|
||||||
mod types;
|
mod types;
|
||||||
|
|
||||||
use lexer::lex;
|
use lexer::lex;
|
||||||
|
|
|
||||||
|
|
@ -1,120 +0,0 @@
|
||||||
/* parser/mod.rs
|
|
||||||
* Eryn Wells <eryn@erynwells.me>
|
|
||||||
*/
|
|
||||||
|
|
||||||
mod nodes;
|
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
use lexer::lex;
|
|
||||||
use lexer::Lex;
|
|
||||||
use lexer::Lexer;
|
|
||||||
use lexer::Token;
|
|
||||||
use self::nodes::Program;
|
|
||||||
use self::nodes::Expression;
|
|
||||||
|
|
||||||
type ParseResult = Result<Program, Error>;
|
|
||||||
|
|
||||||
pub fn parse(input: &str) -> ParseResult {
|
|
||||||
let mut parser = Parser::new(lex(input));
|
|
||||||
parser.parse()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Parser {
|
|
||||||
lexer: Lexer,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Parser {
|
|
||||||
pub fn new(lexer: Lexer) -> Parser {
|
|
||||||
Parser { lexer: lexer }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse(&mut self) -> ParseResult {
|
|
||||||
self.parse_program()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Parser {
|
|
||||||
fn parse_program(&mut self) -> ParseResult {
|
|
||||||
let mut forms: Vec<Expression> = Vec::new();
|
|
||||||
loop {
|
|
||||||
match self.parse_expression() {
|
|
||||||
Ok(expr) => {
|
|
||||||
let is_eof = expr == Expression::EOF;
|
|
||||||
forms.push(expr);
|
|
||||||
if is_eof {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(error) => return Err(error),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(Program::new(forms))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_expression(&mut self) -> Result<Expression, Error> {
|
|
||||||
if let Some(next) = self.lexer.next() {
|
|
||||||
match next.token {
|
|
||||||
Token::Boolean(value) => Ok(Expression::Literal(Box::new(value))),
|
|
||||||
Token::Character(value) => Ok(Expression::Literal(Box::new(value))),
|
|
||||||
_ => Err(Error::new(next, "Invalid token"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Ok(Expression::EOF)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Error {
|
|
||||||
lex: Lex,
|
|
||||||
desc: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error {
|
|
||||||
pub fn new(lex: Lex, desc: &str) -> Error {
|
|
||||||
Error { lex: lex, desc: desc.to_string() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "PARSE ERROR: {}\n token = {:?}", self.desc, self.lex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use super::nodes::*;
|
|
||||||
use lexer::Lexer;
|
|
||||||
use lexer::Token;
|
|
||||||
use types::Boolean;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parses_empty_input() {
|
|
||||||
let r = parse("");
|
|
||||||
assert_eq!(r.unwrap(), Program::new(vec![Expression::EOF]));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parses_single_boolean() {
|
|
||||||
let r = parse("#t");
|
|
||||||
assert_eq!(r.unwrap(), Program::new(vec![Expression::Literal(Box::new(Boolean::new(true))), Expression::EOF]));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parses_single_expression() {
|
|
||||||
let r = parse("(a)");
|
|
||||||
let list = list(vec![Box::new(Expression::Id("a".to_string()))]);
|
|
||||||
assert_eq!(r.unwrap(), Program::new(vec![list, Expression::EOF]));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn list(expr: Vec<Box<Expression>>) -> Expression {
|
|
||||||
Expression::List {
|
|
||||||
left: Token::LeftParen,
|
|
||||||
expr: expr,
|
|
||||||
right: Token::RightParen,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
/* parser/nodes.rs
|
|
||||||
* Eryn Wells <eryn@erynwells.me>
|
|
||||||
*/
|
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
use std::ops::Deref;
|
|
||||||
|
|
||||||
use lexer::Token;
|
|
||||||
use types;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub struct Program {
|
|
||||||
forms: Vec<Expression>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Program {
|
|
||||||
pub fn new(forms: Vec<Expression>) -> Program {
|
|
||||||
Program { forms: forms }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum Expression {
|
|
||||||
EOF,
|
|
||||||
Id(String),
|
|
||||||
Literal(Box<types::Value>),
|
|
||||||
List { left: Token, expr: Vec<Box<Expression>>, right: Token },
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for Expression {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match *self {
|
|
||||||
Expression::EOF => write!(f, "EOF"),
|
|
||||||
Expression::Id(ref id) => write!(f, "Id{{{:?}}}", id),
|
|
||||||
Expression::Literal(ref value) => write!(f, "Literal{{{:?}}}", value),
|
|
||||||
Expression::List{ left: ref lt, ref expr, right: ref rt } => {
|
|
||||||
write!(f, "{:?} {:?} {:?}", lt, expr, rt)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq for Expression {
|
|
||||||
fn eq(&self, other: &Expression) -> bool {
|
|
||||||
match *self {
|
|
||||||
Expression::EOF => self.eq_eof(other),
|
|
||||||
Expression::Id(ref id) => self.eq_id(other, id),
|
|
||||||
Expression::Literal(ref value) => self.eq_literal(other, value.deref()),
|
|
||||||
Expression::List { ref left, ref expr, ref right } => {
|
|
||||||
self.eq_list(other, left, expr, right)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Expression {
|
|
||||||
fn eq_eof(&self, other: &Expression) -> bool {
|
|
||||||
match *other {
|
|
||||||
Expression::EOF => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn eq_id(&self, other: &Expression, id: &str) -> bool {
|
|
||||||
match *other {
|
|
||||||
Expression::Id(ref oid) => id == oid,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn eq_literal(&self, other: &Expression, value: &types::Value) -> bool {
|
|
||||||
match *other {
|
|
||||||
Expression::Literal(ref ovalue) => value == ovalue.deref(),
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn eq_list(&self, other: &Expression, left: &Token, expr: &Vec<Box<Expression>>, right: &Token) -> bool {
|
|
||||||
match *other {
|
|
||||||
Expression::List { left: ref olt, expr: ref oexpr, right: ref ort } => {
|
|
||||||
let left_eq = left == olt;
|
|
||||||
let right_eq = right == ort;
|
|
||||||
let expr_eq = expr == oexpr;
|
|
||||||
left_eq && expr_eq && right_eq
|
|
||||||
},
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue