Replace src/parse/combinators.rs with Nyst
This commit is contained in:
parent
37695f8d63
commit
257c948c3b
58
Cargo.lock
generated
58
Cargo.lock
generated
@ -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"
|
||||
|
@ -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 = "*"
|
||||
|
@ -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> {
|
||||
|
@ -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 {
|
@ -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, "")
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user