forked from AbleScript/ablescript
Starting work on parser improvements
- Parser should parse single expressions
This commit is contained in:
parent
19762e940a
commit
cc4ec803c4
|
@ -8,7 +8,8 @@ pub struct Error {
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ErrorKind {
|
pub enum ErrorKind {
|
||||||
SyntaxError,
|
SyntaxError(String),
|
||||||
|
EndOfTokenStream,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
|
|
|
@ -32,7 +32,7 @@ fn main() {
|
||||||
|
|
||||||
// Parse
|
// Parse
|
||||||
let mut parser = Parser::new(&source);
|
let mut parser = Parser::new(&source);
|
||||||
let ast = parser.parse();
|
let ast = parser.init();
|
||||||
println!("{:#?}", ast);
|
println!("{:#?}", ast);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
|
|
@ -11,6 +11,7 @@ use logos::Logos;
|
||||||
/// Parser structure / state machine
|
/// Parser structure / state machine
|
||||||
pub struct Parser<'a> {
|
pub struct Parser<'a> {
|
||||||
lexer: logos::Lexer<'a, Token>,
|
lexer: logos::Lexer<'a, Token>,
|
||||||
|
ast: Vec<Expr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Parser<'a> {
|
impl<'a> Parser<'a> {
|
||||||
|
@ -18,9 +19,33 @@ impl<'a> Parser<'a> {
|
||||||
pub fn new(source: &'a str) -> Self {
|
pub fn new(source: &'a str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
lexer: Token::lexer(source),
|
lexer: Token::lexer(source),
|
||||||
|
ast: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn init(&mut self) -> Result<Vec<Expr>, Error> {
|
||||||
|
loop {
|
||||||
|
let token = self.lexer.next();
|
||||||
|
if token.is_none() {
|
||||||
|
return Ok(self.ast.clone());
|
||||||
|
};
|
||||||
|
let expr = self.parse_expr(&token)?;
|
||||||
|
self.ast.push(expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_expr(&mut self, token: &Option<Token>) -> Result<Expr, Error> {
|
||||||
|
if matches!(token, None) {
|
||||||
|
return Err(Error {
|
||||||
|
kind: ErrorKind::EndOfTokenStream,
|
||||||
|
position: self.lexer.span(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(todo!())
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/// Start parsing Token Vector into Abstract Syntax Tree
|
/// Start parsing Token Vector into Abstract Syntax Tree
|
||||||
pub fn parse(&mut self) -> Vec<Expr> {
|
pub fn parse(&mut self) -> Vec<Expr> {
|
||||||
let mut ast = vec![];
|
let mut ast = vec![];
|
||||||
|
@ -46,6 +71,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
ast
|
ast
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/// Parse variable declaration
|
/// Parse variable declaration
|
||||||
///
|
///
|
||||||
|
@ -62,7 +88,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error {
|
return Err(Error {
|
||||||
kind: ErrorKind::SyntaxError,
|
kind: ErrorKind::SyntaxError("Unexpected token".to_owned()),
|
||||||
position: self.lexer.span(),
|
position: self.lexer.span(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -80,7 +106,7 @@ impl<'a> Parser<'a> {
|
||||||
// TODO: Arguments
|
// TODO: Arguments
|
||||||
self.require(Token::RightParenthesis)?;
|
self.require(Token::RightParenthesis)?;
|
||||||
self.require(Token::LeftBrace)?;
|
self.require(Token::LeftBrace)?;
|
||||||
let body = self.parse();
|
let body = vec![];
|
||||||
|
|
||||||
Ok(Expr::FunctionDeclaration { iden, body })
|
Ok(Expr::FunctionDeclaration { iden, body })
|
||||||
}
|
}
|
||||||
|
@ -91,7 +117,21 @@ impl<'a> Parser<'a> {
|
||||||
fn bff_declaration(&mut self) -> Result<Expr, Error> {
|
fn bff_declaration(&mut self) -> Result<Expr, Error> {
|
||||||
let iden = self.require(Token::Identifier)?;
|
let iden = self.require(Token::Identifier)?;
|
||||||
self.require(Token::LeftBrace)?;
|
self.require(Token::LeftBrace)?;
|
||||||
let code = self.require(Token::String)?; // <-- Nasty hack, but works
|
let mut code = String::new();
|
||||||
|
while let Some(token) = self.lexer.next() {
|
||||||
|
code.push_str(match token {
|
||||||
|
Token::OpGt
|
||||||
|
| Token::OpLt
|
||||||
|
| Token::Addition
|
||||||
|
| Token::Subtract
|
||||||
|
| Token::FullStop
|
||||||
|
| Token::Comma
|
||||||
|
| Token::LeftBracket
|
||||||
|
| Token::RightBracket => self.lexer.slice(),
|
||||||
|
Token::RightBrace => break,
|
||||||
|
_ => break,
|
||||||
|
});
|
||||||
|
}
|
||||||
self.require(Token::RightBrace)?;
|
self.require(Token::RightBrace)?;
|
||||||
Ok(Expr::BfFDeclaration { iden, code })
|
Ok(Expr::BfFDeclaration { iden, code })
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ impl<'a> Parser<'a> {
|
||||||
Ok(self.lexer.slice().to_owned())
|
Ok(self.lexer.slice().to_owned())
|
||||||
} else {
|
} else {
|
||||||
Err(Error {
|
Err(Error {
|
||||||
kind: ErrorKind::SyntaxError,
|
kind: ErrorKind::SyntaxError("Mysterious parse error".to_owned()),
|
||||||
position: self.lexer.span(),
|
position: self.lexer.span(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,12 @@ pub enum Token {
|
||||||
#[token(";")]
|
#[token(";")]
|
||||||
Semicolon,
|
Semicolon,
|
||||||
|
|
||||||
|
#[token(".")]
|
||||||
|
FullStop,
|
||||||
|
|
||||||
|
#[token(",")]
|
||||||
|
Comma,
|
||||||
|
|
||||||
#[regex(r"#.*")]
|
#[regex(r"#.*")]
|
||||||
Comment,
|
Comment,
|
||||||
|
|
||||||
|
@ -63,6 +69,19 @@ pub enum Token {
|
||||||
#[token("=")]
|
#[token("=")]
|
||||||
Assignment,
|
Assignment,
|
||||||
|
|
||||||
|
// Logical operators
|
||||||
|
#[token("<")]
|
||||||
|
OpLt,
|
||||||
|
|
||||||
|
#[token(">")]
|
||||||
|
OpGt,
|
||||||
|
|
||||||
|
#[token("==")]
|
||||||
|
OpEq,
|
||||||
|
|
||||||
|
#[token("!=")]
|
||||||
|
OpNeq,
|
||||||
|
|
||||||
/// Base52 based character ('a')
|
/// Base52 based character ('a')
|
||||||
#[token("'.*'")]
|
#[token("'.*'")]
|
||||||
Char,
|
Char,
|
||||||
|
|
Loading…
Reference in a new issue