[ create a new paste ] login | about

Link: http://codepad.org/YAj17QGg    [ raw code | fork ]

k4st - C++, pasted on Jan 3:
/*
 * main.cpp
 *
 *  Created on: Dec 8, 2010
 *      Author: Peter Goodman
 *     Version: $Id: main.cpp 6 2011-01-03 22:20:52Z peter.goodman $
 *
 * Copyright 2011 Peter Goodman, all rights reserved.
 */

#include <cstring>
#include <cmath>

#include "src/peg/PEG.hpp"

class CalcTraits {
public:
    typedef char token_type;
    typedef double result_type;
    typedef char terminal_type;

    static unsigned terminal_to_unsigned(terminal_type tt) {
        return static_cast<unsigned>(tt);
    }

    static terminal_type token_to_terminal(const token_type *tok) {
        return *tok;
    }
};

template <template<typename> class R>
class Calc : public cp::peg::Grammar<CalcTraits> {
public:

    static result_type add(result_type left, result_type right) throw() {
        return left + right;
    }
    static result_type sub(result_type left, result_type right) throw() {
        return left - right;
    }
    static result_type mul(result_type left, result_type right) throw() {
        return left * right;
    }
    static result_type div(result_type left, result_type right) throw() {
        return left / right;
    }
    static result_type negate(result_type x) throw() {
        return -x;
    }
    static result_type exp(result_type left, result_type right) throw() {
        return static_cast<result_type>(pow(left, right));
    }
    static result_type shift(result_type old, result_type digit) throw() {
        return (old * 10.0) + digit;
    }
    static result_type char_to_number(const token_type cc) throw() {
        return 0.0 + static_cast<result_type>(cc - '0');
    }

    class result { };
    class factor { };
    class number { };
    class digit { };
    class calc { };

    static void definition(void) throw() {

        R<calc>::add(V<result,P>() << T<'\0'>()).action(identity);
        R<calc>::add(T<'\0'>()).action(nothing);

        R<result>::add(V<result,P>() << T<'*'>() << V<result,P>()).action(mul);
        R<result>::add(V<result,P>() << T<'/'>() << V<result,P>()).action(div);
        R<result>::add(V<result,P>() << T<'+'>() << V<result,P>()).action(add);
        R<result>::add(V<result,P>() << T<'-'>() << V<result,P>()).action(sub);
        R<result>::add(V<factor,P>()).action(identity);

        R<factor>::add(V<factor,P>() << T<'^'>() >> V<factor,P>()).action(exp);
        R<factor>::add(V<number,P>()).action(identity);
        R<factor>::add(T<'-'>() << V<result,P>()).action(negate);
        R<factor>::add(T<'('>() << V<result,P>() << T<')'>()).action(identity);
        R<factor>::add(V<number,P>()).action(identity);

        R<number>::add(V<number,P>() << V<digit,P>()).action(shift);
        R<number>::add(V<digit,P>()).action(identity);

        R<digit>::add(T<'0',P>()).action(char_to_number);
        R<digit>::add(T<'1',P>()).action(char_to_number);
        R<digit>::add(T<'2',P>()).action(char_to_number);
        R<digit>::add(T<'3',P>()).action(char_to_number);
        R<digit>::add(T<'4',P>()).action(char_to_number);
        R<digit>::add(T<'5',P>()).action(char_to_number);
        R<digit>::add(T<'6',P>()).action(char_to_number);
        R<digit>::add(T<'7',P>()).action(char_to_number);
        R<digit>::add(T<'8',P>()).action(char_to_number);
        R<digit>::add(T<'9',P>()).action(char_to_number);
    }
};

int main(int argc, const char **argv) {

    typedef cp::peg::PEG<Calc> Calculator;

    Calculator::Program instructions(Calculator::compile());
    Calculator::Parser parser(instructions.load());

    if(1 < argc) {
        const char *str(argv[1]);

        instructions.print();

        double result;
        if(parser.run(str, strlen(str) + 1, &result)) {
            printf("\nresult = %f\n", result);
        }
    }

    return 0;
}


Create a new paste based on this one


Comments: