Implement basic parser

This commit is contained in:
2021-05-16 13:04:55 -04:00
parent 3e8dd3f698
commit 6744b68385
4 changed files with 56 additions and 7 deletions

1
.gitignore vendored
View File

@@ -6,3 +6,4 @@
# These are backup files generated by rustfmt # These are backup files generated by rustfmt
**/*.rs.bk **/*.rs.bk
.vscode

View File

@@ -1,4 +1,4 @@
#[derive(Debug)] #[derive(Debug, PartialEq, Eq)]
pub enum Token { pub enum Token {
Identifier(String), Identifier(String),
Boolean(bool), Boolean(bool),
@@ -6,13 +6,19 @@ pub enum Token {
LeftRoundBracket, LeftRoundBracket,
RightRoundBracket, RightRoundBracket,
Quote, Quote,
None,
} }
type Tokens = Vec<Token>; impl Default for Token {
fn default() -> Token {
Token::None
}
}
pub fn read(code: &str) -> () { pub type Tokens = Vec<Token>;
let tokens = scan(code, 0, vec![]);
print!("{:?}", tokens); pub fn read(code: &str) -> Tokens {
scan(code, 0, vec![])
} }
fn scan(code: &str, mut ix: usize, mut tokens: Tokens) -> Tokens { fn scan(code: &str, mut ix: usize, mut tokens: Tokens) -> Tokens {

View File

@@ -1,6 +1,9 @@
mod lexer; mod lexer;
mod parser;
fn main() { fn main() {
let scm_code = "(+ a 32)"; let scm_code = "(+ a (* 32 b) c #t #f)";
lexer::read(scm_code); let tokens = lexer::read(scm_code);
let datum = parser::parse(tokens);
println!("{:?}", datum);
} }

39
src/parser.rs Normal file
View File

@@ -0,0 +1,39 @@
use crate::lexer::Token;
use crate::lexer::Tokens;
#[derive(Debug)]
pub enum Datum {
Boolean(bool),
Number(i64),
Symbol(String),
List(Vec<Datum>),
}
pub fn parse(tokens: Tokens) -> Datum {
let (datum, _) = parse_datum(&tokens, 0);
datum
}
fn parse_datum(tokens: &Tokens, ix: usize) -> (Datum, usize) {
match &tokens[ix] {
Token::Identifier(s) => (Datum::Symbol(s.to_string()), ix + 1),
Token::Boolean(b) => (Datum::Boolean(*b), ix + 1),
Token::Number(n) => (Datum::Number(*n), ix + 1),
Token::LeftRoundBracket => parse_list(tokens, ix + 1),
_ => panic!("Unexpected token {:?}", tokens[ix])
}
}
pub fn parse_list(tokens: &Tokens, mut ix: usize) -> (Datum, usize) {
let mut datums = vec![];
// FIXME: will crash when RightRoundBracket is missing
while tokens[ix] != Token::RightRoundBracket {
let (datum, new_ix) = parse_datum(tokens, ix);
datums.push(datum);
ix = new_ix;
}
(Datum::List(datums), ix + 1)
}