diff options
Diffstat (limited to 'src/mp-equation.c')
-rw-r--r-- | src/mp-equation.c | 273 |
1 files changed, 47 insertions, 226 deletions
diff --git a/src/mp-equation.c b/src/mp-equation.c index cec5536..9b6a195 100644 --- a/src/mp-equation.c +++ b/src/mp-equation.c @@ -1,33 +1,21 @@ -/* Copyright (c) 2004-2008 Sami Pietila - * Copyright (c) 2008-2009 Robert Ancell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. +/* + * Copyright (C) 2004-2008 Sami Pietila + * Copyright (C) 2008-2011 Robert Ancell. + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. See http://www.gnu.org/copyleft/gpl.html the full text of the + * license. */ #include <ctype.h> - -#include "mp-equation-private.h" -#include "mp-equation-parser.h" -#include "mp-equation-lexer.h" - -extern int _mp_equation_parse(yyscan_t yyscanner); - +#include <string.h> +#include <stdlib.h> +#include "parser.h" static int -variable_is_defined(MPEquationParserState *state, const char *name) +variable_is_defined(ParserState *state, const char *name) { /* FIXME: Make more generic */ if (strcmp(name, "e") == 0 || strcmp(name, "i") == 0 || strcmp(name, "π") == 0) @@ -39,7 +27,7 @@ variable_is_defined(MPEquationParserState *state, const char *name) static int -get_variable(MPEquationParserState *state, const char *name, MPNumber *z) +get_variable(ParserState *state, const char *name, MPNumber *z) { int result = 1; @@ -58,7 +46,7 @@ get_variable(MPEquationParserState *state, const char *name, MPNumber *z) } static void -set_variable(MPEquationParserState *state, const char *name, const MPNumber *x) +set_variable(ParserState *state, const char *name, const MPNumber *x) { // Reserved words, e, π, mod, and, or, xor, not, abs, log, ln, sqrt, int, frac, sin, cos, ... if (strcmp(name, "e") == 0 || strcmp(name, "i") == 0 || strcmp(name, "π") == 0) @@ -115,7 +103,7 @@ super_atoi(const char *data) static int -function_is_defined(MPEquationParserState *state, const char *name) +function_is_defined(ParserState *state, const char *name) { char *c, *lower_name; @@ -140,8 +128,8 @@ function_is_defined(MPEquationParserState *state, const char *name) strcmp(lower_name, "re") == 0 || strcmp(lower_name, "im") == 0 || strcmp(lower_name, "sin") == 0 || strcmp(lower_name, "cos") == 0 || strcmp(lower_name, "tan") == 0 || - strcmp(lower_name, "sin⁻¹") == 0 || strcmp(lower_name, "cos⁻¹") == 0 || strcmp(lower_name, "tan⁻¹") == 0 || strcmp(lower_name, "asin") == 0 || strcmp(lower_name, "acos") == 0 || strcmp(lower_name, "atan") == 0 || + strcmp(lower_name, "sin⁻¹") == 0 || strcmp(lower_name, "cos⁻¹") == 0 || strcmp(lower_name, "tan⁻¹") == 0 || strcmp(lower_name, "sinh") == 0 || strcmp(lower_name, "cosh") == 0 || strcmp(lower_name, "tanh") == 0 || strcmp(lower_name, "sinh⁻¹") == 0 || strcmp(lower_name, "cosh⁻¹") == 0 || strcmp(lower_name, "tanh⁻¹") == 0 || strcmp(lower_name, "asinh") == 0 || strcmp(lower_name, "acosh") == 0 || strcmp(lower_name, "atanh") == 0 || @@ -159,7 +147,7 @@ function_is_defined(MPEquationParserState *state, const char *name) static int -get_function(MPEquationParserState *state, const char *name, const MPNumber *x, MPNumber *z) +get_function(ParserState *state, const char *name, const MPNumber *x, MPNumber *z) { char *c, *lower_name; int result = 1; @@ -247,168 +235,12 @@ get_function(MPEquationParserState *state, const char *name, const MPNumber *x, static int -do_convert(const char *units[][2], const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z) -{ - int x_index, z_index; - MPNumber x_factor, z_factor; - - for (x_index = 0; units[x_index][0] != NULL && strcmp(units[x_index][0], x_units) != 0; x_index++); - if (units[x_index][0] == NULL) - return 0; - for (z_index = 0; units[z_index][0] != NULL && strcmp(units[z_index][0], z_units) != 0; z_index++); - if (units[z_index][0] == NULL) - return 0; - - mp_set_from_string(units[x_index][1], 10, &x_factor); - mp_set_from_string(units[z_index][1], 10, &z_factor); - mp_multiply(x, &x_factor, z); - mp_divide(z, &z_factor, z); - - return 1; -} - - -static int -convert(MPEquationParserState *state, const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z) +convert(ParserState *state, const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z) { - const char *length_units[][2] = { - {"parsec", "30857000000000000"}, - {"parsecs", "30857000000000000"}, - {"pc", "30857000000000000"}, - {"lightyear", "9460730472580800"}, - {"lightyears", "9460730472580800"}, - {"ly", "9460730472580800"}, - {"au", "149597870691"}, - {"nm", "1852000"}, - {"mile", "1609.344"}, - {"miles", "1609.344"}, - {"mi", "1609.344"}, - {"kilometer", "1000"}, - {"kilometers", "1000"}, - {"km", "1000"}, - {"kms", "1000"}, - {"cable", "219.456"}, - {"cables", "219.456"}, - {"cb", "219.456"}, - {"fathom", "1.8288"}, - {"fathoms", "1.8288"}, - {"ftm", "1.8288"}, - {"meter", "1"}, - {"meters", "1"}, - {"m", "1"}, - {"yard", "0.9144"}, - {"yd", "0.9144"}, - {"foot", "0.3048"}, - {"feet", "0.3048"}, - {"ft", "0.3048"}, - {"inch", "0.0254"}, - {"inches", "0.0254"}, - {"centimeter", "0.01"}, - {"centimeters", "0.01"}, - {"cm", "0.01"}, - {"cms", "0.01"}, - {"millimeter", "0.001"}, - {"millimeters", "0.001"}, - {"mm", "0.001"}, - {"micrometer", "0.000001"}, - {"micrometers", "0.000001"}, - {"um", "0.000001"}, - {"nanometer", "0.000000001"}, - {"nanometers", "0.000000001"}, - {NULL, NULL} - }; - - const char *area_units[][2] = { - {"hectare", "10000"}, - {"hectares", "10000"}, - {"acre", "4046.8564224"}, - {"acres", "4046.8564224"}, - {"m²", "1"}, - {"cm²", "0.001"}, - {"mm²", "0.000001"}, - {NULL, NULL} - }; - - const char *volume_units[][2] = { - {"m³", "1000"}, - {"gallon", "3.785412"}, - {"gallons", "3.785412"}, - {"gal", "3.785412"}, - {"litre", "1"}, - {"litres", "1"}, - {"liter", "1"}, - {"liters", "1"}, - {"L", "1"}, - {"quart", "0.9463529"}, - {"quarts", "0.9463529"}, - {"qt", "0.9463529"}, - {"pint", "0.4731765"}, - {"pints", "0.4731765"}, - {"pt", "0.4731765"}, - {"millilitre", "0.001"}, - {"millilitres", "0.001"}, - {"milliliter", "0.001"}, - {"milliliters", "0.001"}, - {"mL", "0.001"}, - {"cm³", "0.001"}, - {"mm³", "0.000001"}, - {NULL, NULL} - }; - - const char *weight_units[][2] = { - {"tonne", "1000"}, - {"tonnes", "1000"}, - {"kilograms", "1"}, - {"kilogramme", "1"}, - {"kilogrammes", "1"}, - {"kg", "1"}, - {"kgs", "1"}, - {"pound", "0.45359237"}, - {"pounds", "0.45359237"}, - {"lb", "0.45359237"}, - {"ounce", "0.002834952"}, - {"ounces", "0.002834952"}, - {"oz", "0.002834952"}, - {"gram", "0.001"}, - {"grams", "0.001"}, - {"gramme", "0.001"}, - {"grammes", "0.001"}, - {"g", "0.001"}, - {NULL, NULL} - }; - - const char *time_units[][2] = { - {"year", "31557600"}, - {"years", "31557600"}, - {"day", "86400"}, - {"days", "86400"}, - {"hour", "3600"}, - {"hours", "3600"}, - {"minute", "60"}, - {"minutes", "60"}, - {"second", "1"}, - {"seconds", "1"}, - {"s", "1"}, - {"millisecond", "0.001"}, - {"milliseconds", "0.001"}, - {"ms", "0.001"}, - {"microsecond", "0.000001"}, - {"microseconds", "0.000001"}, - {"us", "0.000001"}, - {NULL, NULL} - }; - - if (do_convert(length_units, x, x_units, z_units, z) || - do_convert(area_units, x, x_units, z_units, z) || - do_convert(volume_units, x, x_units, z_units, z) || - do_convert(weight_units, x, x_units, z_units, z) || - do_convert(time_units, x, x_units, z_units, z)) - return 1; - if (state->options->convert) return state->options->convert(x, x_units, z_units, z, state->options->callback_data); - - return 0; + else + return 0; } @@ -416,49 +248,44 @@ MPErrorCode mp_equation_parse(const char *expression, MPEquationOptions *options, MPNumber *result, char **error_token) { int ret; - MPEquationParserState state; - yyscan_t yyscanner; - YY_BUFFER_STATE buffer; + int err; + ParserState* state; + state = p_create_parser (expression, options); if (!(expression && result) || strlen(expression) == 0) return PARSER_ERR_INVALID; - memset(&state, 0, sizeof(MPEquationParserState)); - state.options = options; - state.variable_is_defined = variable_is_defined; - state.get_variable = get_variable; - state.set_variable = set_variable; - state.function_is_defined = function_is_defined; - state.get_function = get_function; - state.convert = convert; - state.error = 0; - + state->variable_is_defined = variable_is_defined; + state->get_variable = get_variable; + state->set_variable = set_variable; + state->function_is_defined = function_is_defined; + state->get_function = get_function; + state->convert = convert; + state->error = 0; mp_clear_error(); - - _mp_equation_lex_init_extra(&state, &yyscanner); - buffer = _mp_equation__scan_string(expression, yyscanner); - - ret = _mp_equation_parse(yyscanner); - if (state.error_token != NULL && error_token != NULL) { - *error_token = state.error_token; + ret = p_parse (state); + if (state->error_token != NULL && error_token != NULL) { + *error_token = state->error_token; } - - _mp_equation__delete_buffer(buffer, yyscanner); - _mp_equation_lex_destroy(yyscanner); - /* Error during parsing */ - if (state.error) - return state.error; + if (state->error) { + err = state->error; + p_destroy_parser (state); + return err; + } - if (mp_get_error()) + if (mp_get_error()) { + p_destroy_parser (state); return PARSER_ERR_MP; + } /* Failed to parse */ - if (ret) + if (ret) { + p_destroy_parser (state); return PARSER_ERR_INVALID; - - mp_set_from_mp(&state.ret, result); - + } + mp_set_from_mp(&state->ret, result); + p_destroy_parser (state); return PARSER_ERR_NONE; } @@ -486,9 +313,3 @@ mp_error_code_to_string(MPErrorCode error_code) return "Unknown parser error"; } } - - -int _mp_equation_error(void *yylloc, MPEquationParserState *state, char *text) -{ - return 0; -} |