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",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "arrayvec"
|
|
||||||
version = "0.5.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
@ -27,12 +21,6 @@ version = "1.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "0.1.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@ -45,19 +33,6 @@ version = "0.2.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a"
|
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]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.3.3"
|
version = "2.3.3"
|
||||||
@ -65,22 +40,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nyst"
|
||||||
version = "5.1.2"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
|
checksum = "e268c6d6d5d5da20b69ab42e6ca2900ae75104db56d9fc4922a831499925c246"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lexical-core",
|
"regex",
|
||||||
"memchr",
|
"ron",
|
||||||
"version_check",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pivot"
|
name = "pivot"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nom",
|
"nyst",
|
||||||
"regex",
|
|
||||||
"ron",
|
"ron",
|
||||||
"serde",
|
"serde",
|
||||||
"wat",
|
"wat",
|
||||||
@ -133,12 +107,6 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ryu"
|
|
||||||
version = "1.0.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.117"
|
version = "1.0.117"
|
||||||
@ -159,12 +127,6 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "static_assertions"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.52"
|
version = "1.0.52"
|
||||||
@ -191,12 +153,6 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "version_check"
|
|
||||||
version = "0.9.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wast"
|
name = "wast"
|
||||||
version = "28.0.0"
|
version = "28.0.0"
|
||||||
|
@ -7,11 +7,8 @@ description = "Pivot is a new programming language built with Rust by Garen Tyle
|
|||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/garentyler/pivot"
|
repository = "https://github.com/garentyler/pivot"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
regex = "1.4.1"
|
|
||||||
nom = "5.1.2"
|
|
||||||
ron = "0.6.2"
|
ron = "0.6.2"
|
||||||
serde = "1.0.117"
|
serde = "1.0.117"
|
||||||
wat = "1.0.29"
|
wat = "1.0.29"
|
||||||
|
nyst = "*"
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
extern crate regex;
|
|
||||||
extern crate wat;
|
|
||||||
|
|
||||||
pub mod ast;
|
pub mod ast;
|
||||||
pub mod codegen;
|
pub mod codegen;
|
||||||
pub mod parse;
|
pub mod parse;
|
||||||
|
|
||||||
use codegen::{SymbolGenerator, Wasm};
|
use codegen::{SymbolGenerator, Wasm};
|
||||||
|
|
||||||
pub fn compile<T: Into<String>>(src: T) -> Vec<u8> {
|
pub fn compile<T: Into<String>>(src: T) -> Vec<u8> {
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
mod combinators;
|
|
||||||
|
|
||||||
use crate::ast::{AstNode, AstNodeKind};
|
use crate::ast::{AstNode, AstNodeKind};
|
||||||
use combinators::Parser;
|
use nyst::Parser;
|
||||||
use ron::{from_str, to_string};
|
use ron::{from_str, to_string};
|
||||||
|
|
||||||
pub fn parse<T: Into<String>>(src: T) -> AstNode {
|
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