Auto generate AnyNode

This commit is contained in:
dalance 2019-07-11 17:34:36 +09:00
parent fe008b3bad
commit 6bdbad0f0a
10 changed files with 98 additions and 81 deletions

View File

@ -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
View 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
View 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
View 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
View 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![]
}
}

View File

@ -1,3 +1,3 @@
#![recursion_limit = "128"] #![recursion_limit = "128"]
pub mod node; pub mod ast;
pub mod parser; pub mod parser;

View File

@ -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
}
}

View File

@ -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::*;

View File

@ -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;

View File

@ -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::*;