Add lexer, parser, ast, and basic command line interaction

* Add lexer and parser using lrpar crate
* AST is added and constructed via lexer and parser
* Command line program `not` will read a file and parse it

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-09-02 14:40:43 -07:00
parent c25a3b5e2b
commit 2fd340a688
4 changed files with 45 additions and 6 deletions

View File

@@ -1,5 +1,38 @@
use not_python::syn; use not_python::syn::ast;
fn main() { use std::{fs, path::PathBuf};
println!("hell world"); use structopt::StructOpt;
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
#[derive(StructOpt, Debug)]
struct Options {
/// The input file to work with.
///
/// By default, the file will be executed. If -c is passed, it will not run and only compile.
/// Supplying - for the path will read from STDIN.
#[structopt(name = "FILE", parse(from_os_str))]
input: PathBuf,
/*
/// Disassemble object that would be passed to VM and exit before running it.
#[structopt(short = "d", long)]
disassemble: bool,
*/
}
fn main() -> Result<()> {
let opt = Options::from_args();
let text = fs::read_to_string(&opt.input)?;
let ast = match ast::parse(text.as_str()) {
Ok(ast) => ast,
Err(errs) => {
for err in errs {
eprintln!("{}", err);
}
return Err("errors reported, exiting".into());
}
};
println!("{:#?}", ast);
Ok(())
} }

View File

@@ -115,14 +115,16 @@ pub enum Atom {
String(String), String(String),
} }
pub fn parse(text: &str) -> Result<Option<Vec<Stmt>>, Vec<lrpar::LexParseError<u32>>> { pub fn parse(text: &str) -> Result<Option<Vec<Stmt>>, Vec<String>> {
use crate::syn::{lexer, parser}; use crate::syn::{lexer, parser};
let lexerdef = lexer::lexerdef(); let lexerdef = lexer::lexerdef();
let lexer = lexerdef.lexer(text); let lexer = lexerdef.lexer(text);
let (res, errors) = parser::parse(&lexer); let (res, errors) = parser::parse(&lexer);
if !errors.is_empty() { if !errors.is_empty() {
return Err(errors) return Err(errors.into_iter()
.map(|e| e.pp(&lexer, &parser::token_epp))
.collect())
} }
Ok(res.transpose().unwrap()) Ok(res.transpose().unwrap())

View File

@@ -1,5 +1,5 @@
%% %%
[\n;]+ "EOL" [\r\n;]+ "EOL"
[a-zA-Z_][a-zA-Z0-9_]* "IDENT" [a-zA-Z_][a-zA-Z0-9_]* "IDENT"
:[a-zA-Z_][a-zA-Z0-9_]* "SYM" :[a-zA-Z_][a-zA-Z0-9_]* "SYM"
[0-9]+ "NUM" [0-9]+ "NUM"

View File

@@ -12,6 +12,7 @@ Body -> Result<Vec<Stmt>>:
Body 'EOL' Stmt { Body 'EOL' Stmt {
flatten($1, $3) flatten($1, $3)
} }
| Body 'EOL' { $1 }
| Stmt { Ok(vec![$1?]) } | Stmt { Ok(vec![$1?]) }
| { Ok(Vec::new()) } | { Ok(Vec::new()) }
; ;
@@ -48,6 +49,9 @@ AccessExpr -> Result<Expr>:
AtomExpr AccessExprTail { AtomExpr AccessExprTail {
Ok(AccessExpr::new_expr($1?, $2?)) Ok(AccessExpr::new_expr($1?, $2?))
} }
| AtomExpr {
Ok(AccessExpr::new_expr($1?, Default::default()))
}
; ;
AccessExprTail -> Result<Vec<Access>>: AccessExprTail -> Result<Vec<Access>>: