This is a follow up question to a question see: Is there any way of accessing the tokens from a token tree or expression in rust (without stringifing and having to parse) for context.
I am currently trying to Tokenise the input using macros so if I put in an input:
let func: Vec<Symbolic> = symbolic!{fn a * sin(a * x) + x^2}
should output
use Symbolic::*; // Obviously shouldn't output this but just to simplify
vec! [ Identifier("a") , Operator("*") , Function("sin(") , Identifier("a") , Operator("*") ,
Identifier("x") , Seperator(')') , Operator("+") , Identifier("x") , Operator("^") ,
Rational(2,1)
my idea is that when I convert from infix to postfix/rpn any function requires a closing delimiter )
and acts as a unary expression on its child:
*
/ \
sin a
|
*
/ \
a x
so here is my issue I'm using push-down accumulators and for some reason I am getting the error
symbolic!(@munch ( $($rest)* ) -> [ $($accum)* Identifier(stringify!($param)), ])
^ no rules expected this token in macro call
Here is my current code
use Symbolic::*;
#[macro_export]
macro_rules! symbolic{
(fn $($expression:tt)*) => {
symbolic!(@munch ( $($expression)* ) -> [])
};
( @munch ($num:literal $($rest:tt)*) -> [$($accum:tt)*] ) => {
symbolic!(@munch ( $($rest)* ) -> [ $($accum)* Rational($num,1), ])
};
( @munch ($param:ident $($rest:tt)*) -> [$($accum:tt)*] ) => {
symbolic!(@munch ( $($rest)* ) -> [ $($accum)* Identifier(stringify!($param)), ])
};
( @munch ($func:ident ($($expression:tt)*) $($rest:tt)*) -> [$($accum:tt)*] ) => {
symbolic!(@munch ( $($rest)* ) -> [
$($accum)*
Function(stringify!(func)),
symbolic!(@munch ( $($expression)* ) -> []),
Seperator(")")
])
};
( @munch (($($expression:tt)*) $($rest:tt)*) -> [$($accum:tt)*] ) => {
symbolic!(@munch ( $($rest)* ) -> [
$($accum)*
Operator("("),
symbolic!(@munch ( $($expression)* ) -> []),
Seperator(")")
])
};
( @munch (+ $($rest:tt)*) -> [$($accum:tt)*] ) => {
symbolic!(@munch ( $($rest)* ) -> [ $($accum)* Operator('+'), ])
};
( @munch (- $($rest:tt)*) -> [$($accum:tt)*] ) => {
symbolic!(@munch ( $($rest)* ) -> [ $($accum)* Operator('-'), ])
};
( @munch (/ $($rest:tt)*) -> [$($accum:tt)*] ) => {
symbolic!(@munch ( $($rest)* ) -> [ $($accum)* Operator('/'), ])
};
( @munch (. $($rest:tt)*) -> [$($accum:tt)*] ) => {
symbolic!(@munch ( $($rest)* ) -> [ $($accum)* Operator('*'), ])
};
( @munch (^ $($rest:tt)*) -> [$($accum:tt)*] ) => {
symbolic!(@munch ( $($rest)* ) -> [ $($accum)* Operator('^'), ])
};
( @munch () -> [$($accum:tt)*] ) => {
vec![ $($accum)* ]
};
}
this is the new data model
pub enum Symbolic<'a>{
Identifier(&'a str),
Function(&'a str),
Separator(char),
Rational((isize, usize)),
Operator(char)
}
pub enum Node<'a>{
Symbolic(Symbolic<'a>),
Expression{
op: Symbolic<'a>,
buf: Vec<&'a Self>
}
}