Created
April 29, 2016 21:18
-
-
Save pczarn/9b1c9bde2c1346d1298613020876a79d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate runtime; | |
#[derive(Clone, Copy, Debug, Eq, PartialEq)] | |
enum Test { | |
Foo, | |
Bar, | |
} | |
#[test] | |
fn test_layered_parser() { | |
let input = [Test::Foo, Test::Foo]; | |
use runtime::*; | |
#[derive(Clone)] | |
pub enum Value0<I> | |
where I: Infer0 | |
{ | |
None, | |
GS_1057(GS_1057<I>), | |
Stmts_83(()), | |
G_1059(Vec<I::T>), | |
Foo(I::T), | |
G_1061(Vec<I::T>), | |
Start_82(I::V0), | |
} | |
struct TerminalAccessor0; | |
impl TerminalAccessor0 { | |
#[inline] | |
fn foo(&self) -> Symbol { | |
Symbol::from(3usize as u32) | |
} | |
} | |
struct GS_1057<I> | |
where I: Infer0 | |
{ | |
x: Vec<I::T>, | |
} | |
impl<I> Clone for GS_1057<I> | |
where I: Infer0 | |
{ | |
fn clone(&self) -> GS_1057<I> { | |
GS_1057 { x: self.x.clone() } | |
} | |
} | |
macro_rules! G_1059(( $ x : expr ) => { | |
{ let mut cont = $ x ; { cont(Vec::new()); } } }); | |
macro_rules! G_1061(( $ x : expr ) => { | |
{ let mut cont = $ x ; { cont(Vec::new()); } } }); | |
struct ParseFactory0 { | |
grammar: grammar::InternalGrammar, | |
} | |
impl ParseFactory0 { | |
fn new() -> ParseFactory0 { | |
unimplemented!() | |
} | |
fn terminal_accessor(&self) -> TerminalAccessor0 { | |
TerminalAccessor0 | |
} | |
fn new_parse<'g, I>(&'g mut self) -> Parse0<'g, I> | |
where I: 'g + LayerInfer0 | |
{ | |
unimplemented!() | |
} | |
} | |
// --- | |
trait LayerInfer0 { | |
type Infer0: Infer0; | |
} | |
struct LayerVInfer0<I>(::std::marker::PhantomData<(I)>); | |
impl<I> LayerInfer0 for LayerVInfer0<I> | |
where I: Infer0 | |
{ | |
type Infer0 = I; | |
} | |
impl<I> LayerInfer0 for I | |
where I: LayerInfer1 | |
{ | |
type Infer0 = <I::Up as LayerInfer0>::Infer0; | |
} | |
trait Infer0 { | |
type Node: Copy; | |
type T: Copy; | |
type V0; | |
} | |
#[derive(Clone, Copy)] | |
struct ValueInfer0<N, T, V0>(::std::marker::PhantomData<(N, T, V0)>); | |
impl<N, T, V0> Infer0 for ValueInfer0<N, T, V0> | |
where T: Copy, | |
N: Copy | |
{ | |
type Node = N; | |
type T = T; | |
type V0 = V0; | |
} | |
struct Parse0<'g, I> | |
where I: LayerInfer0 + 'g | |
{ | |
array_store: Arena<Value0<I::Infer0>>, | |
bocage: Box<Bocage<'g, 'g, 'g, <I::Infer0 as Infer0>::Node, Value0<I::Infer0>>>, | |
recognizer: Recognizer<'g, | |
'g, | |
Bocage<'g, | |
'g, | |
'g, | |
<I::Infer0 as Infer0>::Node, | |
Value0<I::Infer0>>>, | |
traversal: VTraversal<'g, <I::Infer0 as Infer0>::Node, Value0<I::Infer0>>, | |
result: ::std::slice::Iter<'g, Value0<I::Infer0>>, | |
} | |
impl<'g, I> Parse0<'g, I> | |
where I: LayerInfer0 + 'g | |
{ | |
fn process_events(&mut self) {} | |
fn scan_x(&mut self, token: Symbol, value: <I::Infer0 as Infer0>::Node) { | |
self.recognizer.scan(token, value); | |
} | |
fn advance(&mut self) -> bool { | |
self.recognizer.advance() | |
} | |
} | |
impl<'g, I> Iterator for Parse0<'g, I> | |
where I: LayerInfer0 + 'g | |
{ | |
type Item = &'g <I::Infer0 as Infer0>::V0; | |
fn next(&mut self) -> Option<Self::Item> { | |
match self.result.next() { | |
Some(&Value0::Start_82(ref value)) => Some(value), | |
_ => None, | |
} | |
} | |
} | |
struct Recognize<'g> { | |
recognizer: Recognizer<'g, 'g, NullForest>, | |
} | |
impl<'g> Recognize<'g> { | |
fn process_events(&mut self) {} | |
#[inline] | |
fn scan(&mut self, token: Symbol) { | |
self.recognizer.scan(token, ()); | |
} | |
#[inline] | |
fn advance(&mut self) -> bool { | |
self.recognizer.advance() | |
} | |
#[inline] | |
fn is_finished(&mut self) -> bool { | |
self.recognizer.is_finished() | |
} | |
} | |
#[derive(Clone)] | |
enum Value1<I> | |
where I: Infer1 | |
{ | |
None, | |
Foo_85((I::T, I::T)), | |
Bar(I::T), | |
LowerStart_1233((I::T, I::T)), | |
} | |
struct TerminalAccessor1; | |
impl TerminalAccessor1 { | |
#[inline] | |
fn bar(&self) -> Symbol { | |
Symbol::from(1usize as u32) | |
} | |
} | |
struct Layer1; | |
struct ParseFactory1 { | |
grammar: grammar::InternalGrammar, | |
builder: ParseFactory0, | |
} | |
impl Layer1 { | |
fn new() -> Self { | |
Layer1 | |
} | |
fn with_parse_builder(self, builder: ParseFactory0) -> ParseFactory1 { | |
unimplemented!() | |
} | |
} | |
impl ParseFactory1 { | |
fn terminal_accessor(&self) -> TerminalAccessor1 { | |
TerminalAccessor1 | |
} | |
fn new_parse<'g, I>(&'g mut self) -> Parse1<'g, I> | |
where I: 'g + LayerInfer1 | |
{ | |
unimplemented!() | |
} | |
} | |
struct Parse1<'g, I> | |
where I: LayerInfer1 + 'g | |
{ | |
parse: Box<Parse0<'g, I>>, | |
grammar: &'g grammar::InternalGrammar, | |
exhausted: bool, | |
finished_node: Option<NodeRef<'g, 'g, <I::Infer1 as Infer1>::T, Value1<I::Infer1>>>, | |
array_store: Arena<Value1<I::Infer1>>, | |
bocage: Box<Bocage<'g, 'g, 'g, <I::Infer1 as Infer1>::T, Value1<I::Infer1>>>, | |
traversal: VTraversal<'g, <I::Infer1 as Infer1>::T, Value1<I::Infer1>>, | |
recognizer: Recognizer<'g, | |
'g, | |
Bocage<'g, 'g, 'g, <I::Infer1 as Infer1>::T, Value1<I::Infer1>>>, | |
scanned: Vec<(Symbol, <I::Infer1 as Infer1>::T)>, | |
indices_scanned: Vec<usize>, | |
} | |
impl<'g, I, I1> Parse1<'g, LayerVInfer1<I, I1>> | |
where I: LayerInfer0 + 'g, | |
I::Infer0: Infer0<Node = NodeRef<'g, 'g, I1::T, Value1<I1>>>, | |
I1: Infer1 + 'g | |
{ | |
fn process_events(&mut self) { | |
unimplemented!() | |
} | |
fn scan(&mut self, token: Symbol, value: I1::T) { | |
self.recognizer.scan(token, value); | |
self.scanned.push((token, value)); | |
*self.indices_scanned.last_mut().unwrap() += 1; | |
} | |
fn advance(&mut self) -> bool { | |
self.indices_scanned.push(0); | |
self.exhausted = !self.recognizer.advance(); | |
true | |
} | |
} | |
impl<'g, I> Iterator for Parse1<'g, I> | |
where I: LayerInfer1 + 'g | |
{ | |
type Item = <Parse0<'g, I> as Iterator>::Item; | |
fn next(&mut self) -> Option<Self::Item> { | |
self.parse.next() | |
} | |
} | |
trait LayerInfer1 { | |
type Up: LayerInfer0; | |
type Infer1: Infer1; | |
} | |
struct LayerVInfer1<Up, I>(::std::marker::PhantomData<(Up, I)>); | |
impl<Up, I> LayerInfer1 for LayerVInfer1<Up, I> | |
where Up: LayerInfer0, | |
I: Infer1 | |
{ | |
type Up = Up; | |
type Infer1 = I; | |
} | |
trait Infer1 { | |
type T: Copy; | |
} | |
#[derive(Clone, Copy)] | |
struct ValueInfer1<T>(::std::marker::PhantomData<(T)>); | |
impl<T> Infer1 for ValueInfer1<T> | |
where T: Copy | |
{ | |
type T = T; | |
} | |
struct EnumStream<C> { | |
closure: C, | |
} | |
struct EnumStreamParser<C, D, I> { | |
closure: C, | |
eval_closure: D, | |
builder: ParseFactory1, | |
marker: ::std::marker::PhantomData<I>, | |
} | |
struct Parse<'g, I> | |
where I: LayerInfer1 + 'g | |
{ | |
parse: Box<Parse1<'g, I>>, | |
} | |
impl<C> EnumStream<C> { | |
fn new(closure: C) -> Self { | |
EnumStream { closure: closure } | |
} | |
fn with_parse_builder_and_eval_closure<'g, D, I, I1> | |
(self, | |
builder: ParseFactory1, | |
eval_closure: D) | |
-> EnumStreamParser<C, D, LayerVInfer1<I, I1>> | |
where D: FnMut(&'g mut Parse1<'g, LayerVInfer1<I, I1>>), | |
I: LayerInfer0 + 'g, | |
I1: Infer1 + 'g, | |
I::Infer0: Infer0<Node = NodeRef<'g, 'g, I1::T, Value1<I1>>> | |
{ | |
// + for<'g> LexerInfer<'g> { | |
EnumStreamParser { | |
closure: self.closure, | |
eval_closure: eval_closure, | |
builder: builder, | |
marker: ::std::marker::PhantomData, | |
} | |
} | |
} | |
impl<C, D, I, I1> EnumStreamParser<C, D, LayerVInfer1<I, I1>> { | |
fn parse<'g, Iter>(&'g mut self, into_iter: Iter) -> Parse<'g, LayerVInfer1<I, I1>> | |
where C: Fn(usize, Iter::Item) -> bool, | |
Iter: IntoIterator<Item = I1::T>, | |
Iter::Item: Copy, | |
D: FnMut(&'g mut Parse1<'g, LayerVInfer1<I, I1>>), | |
I: LayerInfer0 + 'g, | |
I1: Infer1 + 'g, | |
I::Infer0: Infer0<Node = NodeRef<'g, 'g, I1::T, Value1<I1>>> | |
{ | |
let tokens = &[self.builder.terminal_accessor().bar()]; | |
let mut parse_box = Box::new(self.builder.new_parse()); | |
let parse: &'g mut Parse1<'g, LayerVInfer1<I, I1>> = unsafe { | |
&mut *(&mut *parse_box as *mut _) | |
}; | |
let mut iter = into_iter.into_iter(); | |
for elem in iter { | |
parse.process_events(); | |
if (self.closure)(0usize, elem) { | |
let token = tokens[0usize]; | |
parse.scan(token, elem); | |
} | |
assert!(parse.advance()); | |
} | |
(self.eval_closure)(parse); | |
Parse { parse: parse_box } | |
} | |
} | |
impl<'g, I> Iterator for Parse<'g, I> | |
where I: LayerInfer1 + 'g | |
{ | |
type Item = <Parse1<'g, I> as Iterator>::Item; | |
fn next(&mut self) -> Option<Self::Item> { | |
self.parse.next() | |
} | |
} | |
// must have to tell the compiler that all lifetime params are equal ('g). | |
type ClosureArg<'g, A, B, C, D, E> = &'g mut Parse1<'g, LayerVInfer1< | |
LayerVInfer0<ValueInfer0<NodeRef<'g, 'g, A, Value1<ValueInfer1<B>>>, C, D>>, | |
ValueInfer1<E> | |
>>; | |
type VTraversal<'g, T, V> = Traversal<'g, 'g, 'g, T, V, NullOrder<'g, 'g, T, V>>; | |
let mut parser = EnumStream::new( | |
|id: usize, item| { | |
match (id, item ) { | |
(0usize, &Test::Bar) => return true, | |
_ => { } | |
} | |
false | |
} | |
).with_parse_builder_and_eval_closure( | |
//^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
// error: type annotations required: cannot resolve `<_ as test_simple::LayerInfer0>::Infer0 == _` | |
Layer1::new().with_parse_builder(ParseFactory0::new()), | |
|mut parse| //: ClosureArg<_, _, _, _, _>| | |
{ | |
let mut cartesian_product = CartesianProduct::new(); | |
let root = parse.parse.recognizer.finished_node(); | |
let &mut Parse0 { traversal: ref mut traversal0, ref mut result, array_store: ref store0, .. } = &mut *parse.parse; | |
traversal0.traverse(root); | |
loop { | |
if let Some(deps) = traversal0.traverse_deps() { | |
for node in deps { | |
match node { | |
TraversalNode::Leaf(node) => { | |
let mut builder = SliceBuilder::new(&store0, 0); | |
let sym = node.terminal ; | |
let mut cartesian_product = CartesianProduct::new(); | |
parse.traversal.traverse(node.value); | |
loop { | |
if let Some(deps) = parse.traversal.traverse_deps() { | |
for node in deps { | |
match node { | |
TraversalNode::Leaf(node) => { | |
let mut builder = SliceBuilder::new(&parse.array_store, 0); | |
let terminal_accessor = TerminalAccessor1; | |
let sym = node.terminal; | |
let value = node.value; | |
let tokens = &[terminal_accessor.bar()]; | |
let value = if sym == tokens[0usize] { | |
Value1::Bar(value) | |
} else { | |
unreachable!() | |
}; | |
builder.reserve(1); | |
builder.push(value); | |
node.result(builder.into_slice()); | |
} | |
TraversalNode::Null(nulling) => { | |
let mut builder = SliceBuilder::new(&parse.array_store, 0); | |
match nulling.symbol.usize() { | |
id => unreachable!("nulling id {}", id), | |
} | |
nulling.result(builder.into_slice()); | |
} | |
} | |
} | |
} else { | |
break; | |
} | |
for node in parse.traversal.traverse_sum() { | |
let count = node.iter().map(|alt| alt.len()).fold(0, |acc, elem| acc + elem); | |
let mut slice_builder = SliceBuilder::new(&parse.array_store, count); | |
for alt in node.iter() { | |
cartesian_product.from_production(&alt); | |
let mut finished = false; | |
loop { | |
let result = { | |
let args = cartesian_product.as_slice(); | |
match alt.action() { | |
0u32 => { | |
let bound_args = (true, args[0usize].clone(), args[1usize].clone()); | |
if let (true, Value1::Bar(arg0), Value1::Bar(arg1)) = bound_args { | |
Value1::Foo_85((arg0, arg1)) | |
} else { | |
unreachable!() | |
} | |
} | |
1u32 => { | |
let bound_args = (true, args[0usize].clone()); | |
if let (true, Value1::Foo_85(arg0)) = bound_args { | |
Value1::LowerStart_1233(arg0) | |
} else { | |
unreachable!() | |
} | |
} | |
_ => unreachable!("rule id {}", alt.action()), | |
} | |
}; | |
slice_builder.push(result); | |
if cartesian_product.next().is_none() { | |
break; | |
} | |
} | |
} | |
node.result(slice_builder.advance_slice()); | |
} | |
} | |
let result = match node.value.get() { | |
Evaluated { values } => values, | |
_ => unreachable!(), | |
}; | |
builder.reserve(result.len()); | |
let upper_terminals = TerminalAccessor0; | |
if sym == upper_terminals.foo() { | |
for value in result { | |
let inner = if let Value1::Foo_85(inner) = value.clone() { | |
inner | |
} else { | |
unreachable!() | |
}; | |
builder.push(Value0::Foo(inner)); | |
} | |
} else { | |
unreachable!("wrong sym") | |
} | |
node.result(builder.into_slice()); | |
} | |
TraversalNode::Null(nulling) => { | |
let mut builder = SliceBuilder::new(&store0, 0); | |
match nulling.symbol.usize() { | |
2usize => { | |
builder.reserve(1usize); | |
G_1059!(|result| { | |
builder.push(Value0::G_1059(result)); | |
}) ; | |
} | |
4usize => { | |
builder.reserve(1usize); | |
G_1061!(|result| { | |
builder.push(Value0::G_1061(result)); | |
}) ; | |
} | |
id => unreachable!("nulling id {}", id), | |
} | |
nulling.result(builder.into_slice()); | |
} | |
} | |
} | |
} else { | |
break; | |
} | |
for node in traversal0.traverse_sum() { | |
let count = node.iter() | |
.map(|alt| alt.len()) | |
.fold(0, |acc, elem| acc + elem); | |
let mut slice_builder = SliceBuilder::new(&store0, count); | |
for alt in node.iter() { | |
cartesian_product.from_production(&alt); | |
let mut finished = false; | |
loop { | |
let result = { | |
let args = cartesian_product.as_slice(); | |
match alt.action() { | |
0u32 => { | |
let bound_args = (true, args[1usize].clone()); | |
if let (true, Value0::G_1059(x)) = bound_args { | |
Value0::GS_1057(GS_1057 { x: x }) | |
} else { | |
unreachable!() | |
} | |
} | |
1u32 => { | |
let bound_args = (true, args[1usize].clone()); | |
if let (true, Value0::G_1061(x)) = bound_args { | |
Value0::GS_1057(GS_1057 { x: x }) | |
} else { | |
unreachable!() | |
} | |
} | |
2u32 => { | |
let bound_args = (true, args[0usize].clone()); | |
if let (true, Value0::GS_1057(GS_1057 { x })) = bound_args { | |
Value0::Start_82({ | |
x | |
}) | |
} else { | |
unreachable!() | |
} | |
} | |
3u32 => { | |
let bound_args = (true,); | |
if let (true,) = bound_args { | |
Value0::Stmts_83(()) | |
} else { | |
unreachable!() | |
} | |
} | |
4u32 => { | |
let seq_vec = args.iter().map(|arg| { | |
if let (true, Value0::Foo(elem)) = (true, (*arg).clone()) { | |
elem | |
} else { | |
unreachable!() | |
} | |
}) | |
.collect::<Vec<_>>(); | |
Value0::G_1059(seq_vec) | |
} | |
5u32 => { | |
let seq_vec = args.iter().map(|arg| { | |
if let (true, Value0::Foo(elem)) = (true, (*arg).clone()) { | |
elem | |
} else { | |
unreachable!() | |
} | |
}) | |
.collect::<Vec<_>>(); | |
Value0::G_1061(seq_vec) | |
} | |
_ => unreachable!(), | |
} | |
}; | |
slice_builder.push(result); | |
if cartesian_product.next().is_none() { | |
break; | |
} | |
} | |
} | |
node.result(slice_builder.advance_slice()); | |
} | |
} | |
*result = match root.get() { | |
Evaluated { values } => values.iter(), | |
_ => unreachable!() | |
}; | |
} | |
); | |
let mut iter = parser.parse(&input); | |
let foo = Test::Foo; | |
let v = vec![(&foo, &foo)]; | |
assert_eq!(iter.next(), Some(&v)); | |
assert_eq!(iter.next(), Some(&v)); | |
assert_eq!(iter.next(), None); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment