Some basic parsing works (fixing order of operations), and one test case.

This commit is contained in:
2020-08-13 10:15:32 -07:00
parent 2881c5104a
commit 91d5d1b4fd
7 changed files with 137 additions and 50 deletions

View File

@@ -1,21 +1,25 @@
use lalrpop_util::lalrpop_mod;
mod tokens;
mod token_stream;
mod tokens;
lalrpop_mod!(parser, "/syntax/parser.rs");
mod ast;
pub use crate::syntax::ast::*;
use crate::syntax::parser::ProgramParser;
use crate::syntax::tokens::Token;
use crate::syntax::token_stream::{LexerError, Location, TokenStream};
use crate::syntax::tokens::Token;
#[cfg(test)]
use crate::util::istring::InternedString;
use lalrpop_util::ParseError;
use std::fs;
use std::io;
use std::str::FromStr;
#[derive(Debug)]
pub enum ParserError {
IOError(io::Error),
ParseError(ParseError<Location,Token,LexerError>),
ParseError(ParseError<Location, Token, LexerError>),
}
impl From<io::Error> for ParserError {
@@ -24,7 +28,7 @@ impl From<io::Error> for ParserError {
}
}
impl From<ParseError<Location,Token,LexerError>> for ParserError {
impl From<ParseError<Location, Token, LexerError>> for ParserError {
fn from(x: ParseError<Location, Token, LexerError>) -> Self {
ParserError::ParseError(x)
}
@@ -37,4 +41,51 @@ impl Program {
let lexer = TokenStream::from_file(filename, &mut buffer)?;
Ok(ProgramParser::new().parse(lexer)?)
}
}
fn parse(filename: &str, buffer: &mut String) -> Result<Program, ParserError> {
let lexer = TokenStream::new(filename, buffer);
Ok(ProgramParser::new().parse(lexer)?)
}
}
impl FromStr for Program {
type Err = ParserError;
fn from_str(s: &str) -> Result<Program, ParserError> {
let mut s2 = s.to_string();
Program::parse("<from_str>", &mut s2)
}
}
#[test]
fn order_of_operations() {
let muladd1 = "1 + 2 * 3";
let testfile = InternedString::new("<from_str>");
assert_eq!(
Program::from_str(muladd1).unwrap(),
Program {
statements: vec![],
result: Expression::Primitive(
Location::InFile(testfile, 2),
"+".to_string(),
vec![
Expression::Value(Location::InFile(testfile, 0), Value::Number(None, 1)),
Expression::Primitive(
Location::InFile(testfile, 6),
"*".to_string(),
vec![
Expression::Value(
Location::InFile(testfile, 4),
Value::Number(None, 2),
),
Expression::Value(
Location::InFile(testfile, 8),
Value::Number(None, 3),
),
]
)
]
)
}
);
}