Auto generate AnyNode
This commit is contained in:
parent
fe008b3bad
commit
6bdbad0f0a
@ -9,9 +9,14 @@ license = "MIT"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
description = ""
|
description = ""
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nom = "5.0.0"
|
nom = "5.0.0"
|
||||||
nom_locate = { git = "https://github.com/fflorent/nom_locate" }
|
nom_locate = { git = "https://github.com/fflorent/nom_locate" }
|
||||||
str-concat = "*"
|
str-concat = "*"
|
||||||
node_derive = { path = "./node_derive" }
|
node_derive = { path = "./node_derive" }
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
walkdir = "2"
|
||||||
|
regex = "1"
|
||||||
|
40
build.rs
Normal file
40
build.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
use regex::Regex;
|
||||||
|
use std::env;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{BufRead, BufReader, Write};
|
||||||
|
use std::path::Path;
|
||||||
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let out_dir = env::var("OUT_DIR").unwrap();
|
||||||
|
let dest = Path::new(&out_dir).join("any_node.rs");
|
||||||
|
let mut out = File::create(&dest).unwrap();
|
||||||
|
|
||||||
|
let _ = write!(out, "#[derive(Debug, Clone, AnyNode)]\n");
|
||||||
|
let _ = write!(out, "pub enum AnyNode<'a> {{\n");
|
||||||
|
let _ = write!(out, " Span(&'a Span<'a>),\n");
|
||||||
|
|
||||||
|
let re_node = Regex::new(r"#\[derive.*Node.*\]").unwrap();
|
||||||
|
|
||||||
|
for entry in WalkDir::new("src/parser") {
|
||||||
|
let entry = entry.unwrap();
|
||||||
|
if entry.file_type().is_file() {
|
||||||
|
let f = File::open(entry.path()).unwrap();
|
||||||
|
let f = BufReader::new(f);
|
||||||
|
let mut hit_node = false;
|
||||||
|
for line in f.lines() {
|
||||||
|
let line = line.unwrap();
|
||||||
|
if hit_node {
|
||||||
|
let name = line.split_whitespace().nth(2).unwrap().replace("<'a>", "");
|
||||||
|
let _ = write!(out, " {}(&'a {}<'a>),\n", name, name);
|
||||||
|
hit_node = false;
|
||||||
|
}
|
||||||
|
if re_node.is_match(&line) {
|
||||||
|
hit_node = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = write!(out, "}}\n");
|
||||||
|
}
|
5
src/ast.rs
Normal file
5
src/ast.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
pub mod any_node;
|
||||||
|
pub mod node;
|
||||||
|
pub use any_node::*;
|
||||||
|
pub use node::*;
|
||||||
|
pub use node_derive::*;
|
28
src/ast/any_node.rs
Normal file
28
src/ast/any_node.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use crate::ast::*;
|
||||||
|
use crate::parser::*;
|
||||||
|
|
||||||
|
impl<'a> From<&'a Span<'a>> for AnyNode<'a> {
|
||||||
|
fn from(x: &'a Span<'a>) -> Self {
|
||||||
|
AnyNode::Span(x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/any_node.rs"));
|
||||||
|
|
||||||
|
pub struct Iter<'a> {
|
||||||
|
pub next: Vec<AnyNode<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for Iter<'a> {
|
||||||
|
type Item = AnyNode<'a>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let ret = self.next.pop();
|
||||||
|
if let Some(x) = ret.clone() {
|
||||||
|
let mut x = x.next();
|
||||||
|
x.reverse();
|
||||||
|
self.next.append(&mut x);
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
16
src/ast/node.rs
Normal file
16
src/ast/node.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
use crate::ast::*;
|
||||||
|
use crate::parser::*;
|
||||||
|
|
||||||
|
pub trait Node<'a> {
|
||||||
|
fn test(&'a self) -> String;
|
||||||
|
fn next(&'a self) -> Vec<AnyNode<'a>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Node<'a> for Span<'a> {
|
||||||
|
fn test(&'a self) -> String {
|
||||||
|
String::from("")
|
||||||
|
}
|
||||||
|
fn next(&'a self) -> Vec<AnyNode<'a>> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,3 @@
|
|||||||
#![recursion_limit = "128"]
|
#![recursion_limit = "128"]
|
||||||
pub mod node;
|
pub mod ast;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
|
74
src/node.rs
74
src/node.rs
@ -1,74 +0,0 @@
|
|||||||
use crate::parser::*;
|
|
||||||
use node_derive::AnyNode;
|
|
||||||
|
|
||||||
pub trait Node<'a> {
|
|
||||||
fn test(&'a self) -> String;
|
|
||||||
fn next(&'a self) -> Vec<AnyNode<'a>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Node<'a> for Span<'a> {
|
|
||||||
fn test(&'a self) -> String {
|
|
||||||
String::from("")
|
|
||||||
}
|
|
||||||
fn next(&'a self) -> Vec<AnyNode<'a>> {
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&'a Span<'a>> for AnyNode<'a> {
|
|
||||||
fn from(x: &'a Span<'a>) -> Self {
|
|
||||||
AnyNode::Span(x)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, AnyNode)]
|
|
||||||
pub enum AnyNode<'a> {
|
|
||||||
Span(&'a Span<'a>),
|
|
||||||
Symbol(&'a Symbol<'a>),
|
|
||||||
WhiteSpace(&'a WhiteSpace<'a>),
|
|
||||||
Comment(&'a Comment<'a>),
|
|
||||||
Number(&'a Number<'a>),
|
|
||||||
IntegralNumber(&'a IntegralNumber<'a>),
|
|
||||||
DecimalNumber(&'a DecimalNumber<'a>),
|
|
||||||
DecimalNumberBaseUnsigned(&'a DecimalNumberBaseUnsigned<'a>),
|
|
||||||
DecimalNumberBaseXNumber(&'a DecimalNumberBaseXNumber<'a>),
|
|
||||||
DecimalNumberBaseZNumber(&'a DecimalNumberBaseZNumber<'a>),
|
|
||||||
BinaryNumber(&'a BinaryNumber<'a>),
|
|
||||||
OctalNumber(&'a OctalNumber<'a>),
|
|
||||||
HexNumber(&'a HexNumber<'a>),
|
|
||||||
Sign(&'a Sign<'a>),
|
|
||||||
Size(&'a Size<'a>),
|
|
||||||
NonZeroUnsignedNumber(&'a NonZeroUnsignedNumber<'a>),
|
|
||||||
RealNumber(&'a RealNumber<'a>),
|
|
||||||
RealNumberFloating(&'a RealNumberFloating<'a>),
|
|
||||||
FixedPointNumber(&'a FixedPointNumber<'a>),
|
|
||||||
Exp(&'a Exp<'a>),
|
|
||||||
UnsignedNumber(&'a UnsignedNumber<'a>),
|
|
||||||
BinaryValue(&'a BinaryValue<'a>),
|
|
||||||
OctalValue(&'a OctalValue<'a>),
|
|
||||||
HexValue(&'a HexValue<'a>),
|
|
||||||
DecimalBase(&'a DecimalBase<'a>),
|
|
||||||
BinaryBase(&'a BinaryBase<'a>),
|
|
||||||
OctalBase(&'a OctalBase<'a>),
|
|
||||||
HexBase(&'a HexBase<'a>),
|
|
||||||
XNumber(&'a XNumber<'a>),
|
|
||||||
ZNumber(&'a ZNumber<'a>),
|
|
||||||
UnbasedUnsizedLiteral(&'a UnbasedUnsizedLiteral<'a>),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Iter<'a> {
|
|
||||||
pub(crate) next: Vec<AnyNode<'a>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Iterator for Iter<'a> {
|
|
||||||
type Item = AnyNode<'a>;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
let ret = self.next.pop();
|
|
||||||
if let Some(x) = ret.clone() {
|
|
||||||
let mut x = x.next();
|
|
||||||
self.next.append(&mut x);
|
|
||||||
}
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,5 @@
|
|||||||
use crate::node::*;
|
use crate::ast::*;
|
||||||
use crate::parser::*;
|
use crate::parser::*;
|
||||||
use node_derive::Node;
|
|
||||||
use nom::branch::*;
|
use nom::branch::*;
|
||||||
use nom::bytes::complete::*;
|
use nom::bytes::complete::*;
|
||||||
use nom::character::complete::*;
|
use nom::character::complete::*;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use crate::node::*;
|
use crate::ast::*;
|
||||||
use crate::parser::*;
|
use crate::parser::*;
|
||||||
use node_derive::Node;
|
|
||||||
use nom::branch::*;
|
use nom::branch::*;
|
||||||
use nom::bytes::complete::*;
|
use nom::bytes::complete::*;
|
||||||
use nom::IResult;
|
use nom::IResult;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use crate::node::*;
|
use crate::ast::*;
|
||||||
use crate::parser::*;
|
use crate::parser::*;
|
||||||
use node_derive::Node;
|
|
||||||
use nom::branch::*;
|
use nom::branch::*;
|
||||||
use nom::bytes::complete::*;
|
use nom::bytes::complete::*;
|
||||||
use nom::character::complete::*;
|
use nom::character::complete::*;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user