Replace src/parse/combinators.rs with Nyst

This commit is contained in:
Garen Tyler 2021-02-11 11:35:33 -07:00
parent 37695f8d63
commit 257c948c3b
5 changed files with 10 additions and 290 deletions

58
Cargo.lock generated
View File

@ -9,12 +9,6 @@ dependencies = [
"memchr",
]
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "base64"
version = "0.12.3"
@ -27,12 +21,6 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -45,19 +33,6 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a"
[[package]]
name = "lexical-core"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db65c6da02e61f55dae90a0ae427b2a5f6b3e8db09f58d10efab23af92592616"
dependencies = [
"arrayvec",
"bitflags",
"cfg-if",
"ryu",
"static_assertions",
]
[[package]]
name = "memchr"
version = "2.3.3"
@ -65,22 +40,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
[[package]]
name = "nom"
version = "5.1.2"
name = "nyst"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
checksum = "e268c6d6d5d5da20b69ab42e6ca2900ae75104db56d9fc4922a831499925c246"
dependencies = [
"lexical-core",
"memchr",
"version_check",
"regex",
"ron",
"serde",
]
[[package]]
name = "pivot"
version = "0.1.0"
dependencies = [
"nom",
"regex",
"nyst",
"ron",
"serde",
"wat",
@ -133,12 +107,6 @@ dependencies = [
"serde",
]
[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "serde"
version = "1.0.117"
@ -159,12 +127,6 @@ dependencies = [
"syn",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "syn"
version = "1.0.52"
@ -191,12 +153,6 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "version_check"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
[[package]]
name = "wast"
version = "28.0.0"

View File

@ -7,11 +7,8 @@ description = "Pivot is a new programming language built with Rust by Garen Tyle
license = "MIT"
repository = "https://github.com/garentyler/pivot"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
regex = "1.4.1"
nom = "5.1.2"
ron = "0.6.2"
serde = "1.0.117"
wat = "1.0.29"
nyst = "*"

View File

@ -1,9 +1,7 @@
extern crate regex;
extern crate wat;
pub mod ast;
pub mod codegen;
pub mod parse;
use codegen::{SymbolGenerator, Wasm};
pub fn compile<T: Into<String>>(src: T) -> Vec<u8> {

View File

@ -1,7 +1,5 @@
mod combinators;
use crate::ast::{AstNode, AstNodeKind};
use combinators::Parser;
use nyst::Parser;
use ron::{from_str, to_string};
pub fn parse<T: Into<String>>(src: T) -> AstNode {

View File

@ -1,229 +0,0 @@
use regex::Regex;
use ron::to_string;
use std::ops::Range;
use std::rc::Rc;
pub enum ParserKind {
Regex(Regex),
And,
Ignore,
Or,
RepeatRange(Range<usize>),
Map(Rc<Box<dyn Fn(String) -> Result<String, ron::Error>>>),
Custom(Rc<Box<dyn Fn(String) -> Result<(String, String), String>>>),
}
impl std::fmt::Debug for ParserKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self)
}
}
impl std::fmt::Display for ParserKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use ParserKind::*;
match self {
Regex(r) => write!(f, "Regex /{}/", r.as_str()),
And => write!(f, "And"),
Ignore => write!(f, "Ignore"),
Or => write!(f, "Or"),
RepeatRange(range) => write!(f, "RepeatRange {:?}", range),
Map(_) => write!(f, "Map"),
Custom(_) => write!(f, "Custom"),
}
}
}
impl Clone for ParserKind {
fn clone(&self) -> Self {
use ParserKind::*;
match self {
Regex(r) => Regex(r.clone()),
And => And,
Ignore => Ignore,
Or => Or,
RepeatRange(range) => RepeatRange(range.clone()),
Map(cfn) => Map(Rc::clone(cfn)),
Custom(cfn) => Custom(Rc::clone(cfn)),
}
}
}
impl PartialEq for ParserKind {
fn eq(&self, other: &ParserKind) -> bool {
format!("{}", self) == format!("{}", other)
}
}
#[derive(Debug, Clone)]
pub struct Parser {
kind: ParserKind,
subparsers: Vec<Parser>,
}
impl std::fmt::Display for Parser {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.pretty_print(f, 0)
}
}
impl Parser {
pub fn parse<T: Into<String>>(&self, src: T) -> Result<(String, String), String> {
use ParserKind::*;
let s: String = src.into();
match &self.kind {
Regex(re) => {
if let Some(mat) = re.find(&s) {
if mat.start() == 0 {
Ok((
s[mat.start()..mat.end()].to_owned(),
s[mat.end()..].to_owned(),
))
} else {
Err(s)
}
} else {
Err(s)
}
}
And => {
if self.subparsers[0].kind == Ignore && self.subparsers[1].kind == Ignore {
Ok(("".into(), s))
} else if self.subparsers[0].kind == Ignore {
let (_, rest) = self.subparsers[0].parse(s)?;
self.subparsers[1].parse(rest)
} else if self.subparsers[1].kind == Ignore {
let (matched, lrest) = self.subparsers[0].parse(s.clone())?;
if let Ok((_, rest)) = self.subparsers[1].parse(lrest) {
Ok((matched, rest))
} else {
Err(s)
}
} else {
let (lmatched, lrest) = self.subparsers[0].parse(s)?;
let (rmatched, rrest) = self.subparsers[1].parse(lrest)?;
Ok((
to_string(&vec![lmatched.clone(), rmatched.clone()]).unwrap(),
rrest,
))
}
}
Ignore => Ok(("".into(), self.subparsers[0].parse(s)?.1)),
Or => {
if let Ok(lresult) = self.subparsers[0].parse(s.clone()) {
Ok(lresult)
} else {
self.subparsers[1].parse(s.clone())
}
}
RepeatRange(range) => {
let mut matched = vec![];
let mut rest = s.clone();
// Parse up to range.start
for _ in 0..range.start {
let (m, r) = self.subparsers[0].parse(rest)?;
matched.push(m);
rest = r;
}
// Parse optionally up to range.end
for _ in 0..(range.end - range.start) {
let parse_result = self.subparsers[0].parse(rest);
if let Err(r) = parse_result {
rest = r;
break;
} else {
let (m, r) = parse_result.unwrap();
matched.push(m);
rest = r;
}
}
Ok((to_string(&matched).unwrap(), rest))
}
Map(cfn) => {
let (matched, rest) = self.subparsers[0].parse(s)?;
if let Ok(m) = cfn(matched) {
Ok((m, rest))
} else {
Err(rest)
}
}
Custom(cfn) => cfn(s),
}
}
// Static
pub fn regex<T: Into<String>>(s: T) -> Parser {
Parser {
kind: ParserKind::Regex(Regex::new(&s.into()).expect("could not compile regex")),
subparsers: vec![],
}
}
pub fn custom<F: 'static>(cfn: F) -> Parser
where
F: Fn(String) -> Result<(String, String), String>,
{
Parser {
kind: ParserKind::Custom(Rc::new(Box::new(cfn))),
subparsers: vec![],
}
}
// Instance
pub fn and(self, r: Parser) -> Parser {
Parser {
kind: ParserKind::And,
subparsers: vec![self, r],
}
}
pub fn ignore(self) -> Parser {
Parser {
kind: ParserKind::Ignore,
subparsers: vec![self],
}
}
pub fn or(self, r: Parser) -> Parser {
Parser {
kind: ParserKind::Or,
subparsers: vec![self, r],
}
}
pub fn repeat_range(self, num_repeats: Range<usize>) -> Parser {
Parser {
kind: ParserKind::RepeatRange(num_repeats),
subparsers: vec![self],
}
}
pub fn optional(self) -> Parser {
Parser {
kind: ParserKind::RepeatRange(0..1),
subparsers: vec![self],
}
}
pub fn map<F: 'static>(self, cfn: F) -> Parser
where
F: Fn(String) -> Result<String, ron::Error>,
{
Parser {
kind: ParserKind::Map(Rc::new(Box::new(cfn))),
subparsers: vec![self],
}
}
// Other
pub fn pretty_print(&self, f: &mut std::fmt::Formatter<'_>, indent: usize) -> std::fmt::Result {
for _ in 0..indent {
write!(f, " ")?;
}
write!(f, "{}", self.kind)?;
if self.subparsers.len() > 0 {
write!(f, " [\n")?;
for subparser in &self.subparsers {
subparser.pretty_print(f, indent + 2)?;
write!(f, ",\n")?;
}
for _ in 0..indent {
write!(f, " ")?;
}
write!(f, "]")
} else {
write!(f, "")
}
}
}