Skip to content
Snippets Groups Projects
Commit 0714d5e4 authored by Carlos Valencia's avatar Carlos Valencia
Browse files

*> and <|> work

parent 49664707
No related branches found
No related tags found
1 merge request!3Change macros format
......@@ -60,6 +60,7 @@ impl Parser<i32> for Int {
digits += 1;
(acc * 10) + c
});
let size = zeros + digits;
ctx.index += size;
Ok(s)
......
mod parser;
use std::marker::PhantomData;
use parser::{Parser};
mod combinators;
use combinators::non_primitive_combinators::ThenR;
use combinators::primitive_combinators::Alternative;
use crate::combinators::common::characters::Char;
#[macro_use]
mod preprocessor;
/* Operators
infixr 3 <|>
infixl 4 <*>
infixl 4 <*
infixl 4 *>
infixl 4 <~>
*/
#[macro_use]
macro_rules! infix {
// done converting
(@cvt () $postfix:tt) => { infix!(@pfx () $postfix) };
// | | ^ postfix expression
// | ^ operand stack
// ^ postfix interpreter
// infix to postfix conversion using the rules at the bottom of this page: http://csis.pace.edu/~wolf/CS122/infix-postfix.htm
// at end of input, flush the operators to postfix
(@cvt ($ophead:tt $($optail:tt)*) ($($postfix:tt)*)) => { infix!(@cvt ($($optail)*) ($($postfix)* $ophead)) };
// 2. push an operator onto the stack if it's empty or has a left-paren on top
(@cvt ( ) $postfix:tt <|> $($tail:tt)*) => { infix!(@cvt (<|> ) $postfix $($tail)*) };
(@cvt ( ) $postfix:tt *> $($tail:tt)*) => { infix!(@cvt (*> ) $postfix $($tail)*) };
//(@cvt ( ) $postfix:tt / $($tail:tt)*) => { infix!(@cvt (/ ) $postfix $($tail)*) };
(@cvt (LP $($optail:tt)*) $postfix:tt <|> $($tail:tt)*) => { infix!(@cvt (<|> LP $($optail)*) $postfix $($tail)*) };
(@cvt (LP $($optail:tt)*) $postfix:tt *> $($tail:tt)*) => { infix!(@cvt (*> LP $($optail)*) $postfix $($tail)*) };
//(@cvt (LP $($optail:tt)*) $postfix:tt / $($tail:tt)*) => { infix!(@cvt (/ LP $($optail)*) $postfix $($tail)*) };
// 3. push a left-paren onto the stack
(@cvt ($($operator:tt)*) $postfix:tt ($($inner:tt)*) $($tail:tt)*) => { infix!(@cvt (LP $($operator)*) $postfix $($inner)* RP $($tail)*) };
// 4. see right-paren, pop operators to postfix until left-paren
(@cvt (LP $($optail:tt)*) $postfix:tt RP $($tail:tt)*) => { infix!(@cvt ($($optail)*) $postfix $($tail)*) };
(@cvt ($ophead:tt $($optail:tt)*) ($($postfix:tt)*) RP $($tail:tt)*) => { infix!(@cvt ($($optail)*) ($($postfix)* $ophead) RP $($tail)*) };
// 5. if an operator w/ lower precedence is on top, just push
(@cvt (<|> $($optail:tt)*) $postfix:tt *> $($tail:tt)*) => { infix!(@cvt (*> <|> $($optail)*) $postfix $($tail)*) };
//(@cvt (- $($optail:tt)*) $postfix:tt * $($tail:tt)*) => { infix!(@cvt (* - $($optail)*) $postfix $($tail)*) };
//(@cvt (+ $($optail:tt)*) $postfix:tt / $($tail:tt)*) => { infix!(@cvt (/ + $($optail)*) $postfix $($tail)*) };
//(@cvt (- $($optail:tt)*) $postfix:tt / $($tail:tt)*) => { infix!(@cvt (/ - $($optail)*) $postfix $($tail)*) };
// 6. if an operator w/ equal precedence is on top, pop and push
(@cvt (<|> $($optail:tt)*) ($($postfix:tt)*) <|> $($tail:tt)*) => { infix!(@cvt (<|> $($optail)*) ($($postfix)* <|>) $($tail)*) };
(@cvt (*> $($optail:tt)*) ($($postfix:tt)*) *> $($tail:tt)*) => { infix!(@cvt (*> $($optail)*) ($($postfix)* *>) $($tail)*) };
//(@cvt (/ $($optail:tt)*) ($($postfix:tt)*) / $($tail:tt)*) => { infix!(@cvt (/ $($optail)*) ($($postfix)* /) $($tail)*) };
//(@cvt (* $($optail:tt)*) ($($postfix:tt)*) / $($tail:tt)*) => { infix!(@cvt (/ $($optail)*) ($($postfix)* *) $($tail)*) };
//(@cvt (/ $($optail:tt)*) ($($postfix:tt)*) * $($tail:tt)*) => { infix!(@cvt (* $($optail)*) ($($postfix)* /) $($tail)*) };
// 7. if an operator w/ higher precedence is on top, pop it to postfix
(@cvt (*> $($optail:tt)*) ($($postfix:tt)*) <|> $($tail:tt)*) => { infix!(@cvt ($($optail)*) ($($postfix)* *>) <|> $($tail)*) };
//(@cvt (/ $($optail:tt)*) ($($postfix:tt)*) + $($tail:tt)*) => { infix!(@cvt ($($optail)*) ($($postfix)* /) + $($tail)*) };
// 1. operands go to the postfix output
(@cvt $operators:tt ($($postfix:tt)*) $head:tt $($tail:tt)*) => { infix!(@cvt $operators ($($postfix)* ($head)) $($tail)*) };
// postfix interpreter
(@pfx ($result:expr ) ( )) => { $result };
(@pfx (($a:expr) ($b:expr) $($stack:tt)*) (<|> $($tail:tt)*)) => { infix!(@pfx (((
combinators::primitive_combinators::Alternative {
parser_first:$b,
parser_second: $a,
_t: std::marker::PhantomData
}
)) $($stack)*) ($($tail)*)) };
(@pfx (($a:expr) ($b:expr) $($stack:tt)*) (*> $($tail:tt)*)) => { infix!(@pfx (((
combinators::non_primitive_combinators::ThenR{
parser_first:$b,
parser_second: $a,
_a: std::marker::PhantomData,
_b: std::marker::PhantomData
}
)) $($stack)*) ($($tail)*)) };
//(@pfx (($a:expr) ($b:expr) $($stack:tt)*) (/ $($tail:tt)*)) => { infix!(@pfx ((($b / $a)) $($stack)*) ($($tail)*)) };
(@pfx ($($stack:tt)* ) ($head:tt $($tail:tt)*)) => { infix!(@pfx ($head $($stack)*) ($($tail)*)) };
($($t:tt)*) => { infix!(@cvt () () $($t)*) }
// | | | ^ infix expression
// | | ^ postfix expression
// | ^ operator stack
// ^ convert infix to postfix
}
fn main() {
let p1 = Char {c: 'a'};
let p2 = Char {c: 'b'};
let p3 = Char {c: 'c'};
let p4 = Char {c: 'd'};
let p5 = Char {c: 'e'};
let p = infix!(p1 *> p2 <|> p3 *> p4 <|> p5);
println!("{:#?}", p.parse("e"));
}
This diff is collapsed.
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment