Skip to content

Commit

Permalink
parser
Browse files Browse the repository at this point in the history
  • Loading branch information
sozysozbot committed Jul 19, 2020
1 parent 60a45c6 commit 5d32f9b
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 32 deletions.
25 changes: 0 additions & 25 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
peek-nth = "0.2.0"
ordered-float = "2.0.0"
peek-nth = "0.2.0"
15 changes: 12 additions & 3 deletions src/lex/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub enum Lex {
}

#[derive(Eq, PartialEq, Debug, Clone)]
pub struct IntNum(Vec<IntNumKeywords>);
pub struct IntNum(pub Vec<IntNumKeywords>);

#[derive(Eq, PartialEq, Debug, Clone)]
pub enum FloatNumKeywords {
Expand Down Expand Up @@ -73,7 +73,7 @@ impl FloatNumKeywords {
}

#[derive(Eq, PartialEq, Debug, Clone, Copy)]
enum IntNumKeywords {
pub enum IntNumKeywords {
/// 零
Ling2,
/// 一
Expand Down Expand Up @@ -167,6 +167,15 @@ pub enum BoolValue {
Yang2,
}

impl BoolValue {
pub fn interpret(self) -> bool {
match self {
BoolValue::Yin1 => false,
BoolValue::Yang2 => true,
}
}
}

#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum Type {
/// 數
Expand All @@ -181,7 +190,7 @@ pub enum Type {

use peek_nth::IteratorExt;

#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum Error {
UnexpectedCharAfter(char, char),
UnexpectedEOFAfter(char),
Expand Down
144 changes: 142 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,139 @@
use std::fs::File;
use std::io::prelude::*;
mod lex;
#[derive(Debug)]
enum Statement {
Declare(DeclareStatement),
Print,
// Define,
// For,
// Function,
// If,
// Return,
// Math,
// Assign,
// Import,
// Object,
// Reference,
// Array,
// Flush,
// Break,
// Comment,
}

#[derive(Debug)]
struct DeclareStatement {
int_num: i64,
type_: lex::Type,
data_arr: Vec<Data>,
}

#[derive(Debug)]
enum Data {
StringLiteral(String),
BoolValue(bool),
Identifier(String),
IntNum(i64),
// FloatNum(f64),
}

#[derive(Debug)]
enum ParseError {
UnresolvableTokens,
UnexpectedEOF,
}

fn interpret_intnum(num: &lex::IntNum) -> i64 {
let lex::IntNum(v) = num;
match v.as_slice() {
&[lex::IntNumKeywords::Ling2] => 0,
&[lex::IntNumKeywords::Yi1] => 1,
&[lex::IntNumKeywords::Er4] => 2,
&[lex::IntNumKeywords::San1] => 3,
&[lex::IntNumKeywords::Si4] => 4,
&[lex::IntNumKeywords::Wu3] => 5,
&[lex::IntNumKeywords::Liu4] => 6,
&[lex::IntNumKeywords::Qi1] => 7,
&[lex::IntNumKeywords::Ba1] => 8,
&[lex::IntNumKeywords::Jiu3] => 9,
_ => unimplemented!(),
}
}

fn parse_data(
iter: &mut peek_nth::PeekableNth<std::slice::Iter<'_, lex::Lex>>,
) -> Result<Data, ParseError> {
let token = match iter.next() {
None => return Err(ParseError::UnexpectedEOF),
Some(a) => a,
};

match token {
lex::Lex::StringLiteral(strlit) => Ok(Data::StringLiteral(strlit.to_string())),
lex::Lex::BoolValue(bv) => Ok(Data::BoolValue(bv.interpret())),
lex::Lex::Identifier(ident) => Ok(Data::Identifier(ident.to_string())),
lex::Lex::IntNum(intnum) => Ok(Data::IntNum(interpret_intnum(intnum))), /* FIXME: must handle float */
_ => unimplemented!(),
}
}

fn parse_statement(
mut iter: &mut peek_nth::PeekableNth<std::slice::Iter<'_, lex::Lex>>,
) -> Result<Statement, ParseError> {
let token = match iter.next() {
None => return Err(ParseError::UnexpectedEOF),
Some(a) => a,
};

match token {
lex::Lex::Shu1Zhi1 => return Ok(Statement::Print),
lex::Lex::Jin1You3 | lex::Lex::Wu2You3 => {
let next = iter.next();
match next {
None => return Err(ParseError::UnexpectedEOF),
Some(lex::Lex::IntNum(num)) => {
match iter.next() {
None => return Err(ParseError::UnexpectedEOF),
Some(lex::Lex::Type(t)) => {
let mut ans = vec![];
let vec = loop {
if iter.peek() != Some(&&lex::Lex::Yue1) {
break ans;
}
iter.next();
let data = parse_data(&mut iter)?;
ans.push(data);
};

return Ok(Statement::Declare(DeclareStatement {
int_num: interpret_intnum(num),
type_: *t,
data_arr: vec,
}));
}
_ => unimplemented!(), // 術, 物
}
}
_ => return Err(ParseError::UnresolvableTokens),
}
}
_ => unimplemented!(),
}
}

use peek_nth::IteratorExt;
fn parse(lex: &[lex::Lex]) -> Result<Vec<Statement>, ParseError> {
let mut iter = lex.iter().peekable_nth();

let mut ans = vec![];
loop {
if iter.peek().is_none() {
return Ok(ans);
}

ans.push(parse_statement(&mut iter)?);
}
}

fn main() -> std::io::Result<()> {
let mut file = File::open("test000.wy")?;
Expand All @@ -10,9 +143,16 @@ fn main() -> std::io::Result<()> {
println!("src: \n----------------------");
println!("{}", contents);
println!("----------------------");

let lex = lex::lex(&contents);
println!("\nlexer output: \n----------------------");
println!("{:?}", lex::lex(&contents));
println!("{:?}", lex.clone());
println!("----------------------");

if let Ok(lex) = lex {
let res = parse(&lex);
println!("\nparser output: \n----------------------");
println!("{:?}", res);
println!("----------------------");
}
Ok(())
}

0 comments on commit 5d32f9b

Please sign in to comment.