Menu

How to combine two parser types?

Help
2008-01-05
2013-03-27
  • Jaap de Wolff

    Jaap de Wolff - 2008-01-05

    The parsnip library looks nice, but I am unable two combine two types.

    At this moment I have the calculator, allowing numeric expressions.
    I also made a bool calculator, allowing boolean expressions.

    But what I want to do is something like:

    if (4*2>8)||(4/2<6)
    the tricky point is in the < or the > operator. The prototype for those functions is something like
    "bool greater(int, int)", and when used in a op_table()->infix_left(.) a function is expected with the same return type as the arguments.

    How can I solve this?

    Jaap

     
    • Jaap de Wolff

      Jaap de Wolff - 2008-01-05

      Ok, I figured it out myself already:

      First implement a expr_num, in the same way as in the sample in the original sources.
      Then implement a expr_bool, supporting && || == !=
      But for the term_bool do the following:

          const StrParser num_operator = token(       
              str("==") | str("!=")|
              str(">=") | str("<=")|
              ch('>') | ch('<')
              )  >>= "num_operator";
          BoolParser term_bool =
              call0(fn_true, token_str("true")) |
              call0(fn_false, token_str("false")) |
              call3(fn_numcmp, expr_num >> num_operator >> expr_num) |
              skip_ch('(') >> op_self_bool >> skip_ch(')')
              ;

      where fn_numcmp is:

      bool fn_numcmp(int x, std::string token, int y)
      {
          if (token == ">") return (x > y);
          if (token == "<") return (x < y);
          if (token == ">=") return (x >= y);
          if (token == "<=") return (x <= y);
          if (token == "==") return (x == y);
          if (token == "!=") return (x != y);
          return false;
      }

      it works perfect

       
    • Alex Rubinsteyn

      Alex Rubinsteyn - 2008-01-08

      Hi Jaap,
      To cut down on string comparisons I would just use two optables.

      --------------------------------------------------
      BoolParser bool_term = skip_token_str("true") >> succeed(true) |
                                 skip_token_str("false") >> succeed(false)|
                                 call2(greater, expr >> skip_token_str(">") >> expr) |
                                 call2(less, expr >> skip_token_str("<") >> expr);

      BoolParser bool_ops = op_table(bool_term)
                  ->infix_left("&&", 10, logical_and)
                      ->infix_left("||", 10, logical_or);

      BoolParser bool_expr = bool_ops | bool_term;
      ---------------------------------------------------

      You would also need to add these functions outside main:
      ---------------------------------------------------
      bool logical_or (bool p, bool q) { return p || q; }
      bool logical_and(bool p, bool q) { return p && q; }
      bool greater(double x, double y) { return x > y;  }
      bool less(double x, double y) { return x < y; }
      ---------------------------------------------------

      The main drawback to this approach is that you can't yet easily parse a prefix not operator. That's a limit of the OpTable parser that I plan on fixing in the future.

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.