0

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

0 Answers0