[App] Expression parser allow multi unit inputs (2'2")

This commit is contained in:
Connor Worrell
2023-04-25 20:25:19 -06:00
committed by Adrián Insaurralde Avalos
parent 8a3c8258df
commit f552b72539
5 changed files with 1074 additions and 1156 deletions

View File

@@ -231,9 +231,9 @@ EXPO [eE][-+]?[0-9]+
"cd" COUNTCHARS; yylval.quantity.scaler = Quantity::Candela; yylval.quantity.unitStr = yytext; return UNIT; // Candela (internal standard luminous intensity)
"in" COUNTCHARS; yylval.quantity.scaler = Quantity::Inch; yylval.quantity.unitStr = yytext; return UNIT; // inch
"\"" COUNTCHARS; yylval.quantity.scaler = Quantity::Inch; yylval.quantity.unitStr = yytext; return UNIT; // inch
"\"" COUNTCHARS; yylval.quantity.scaler = Quantity::Inch; yylval.quantity.unitStr = yytext; return USUNIT; // inch
"ft" COUNTCHARS; yylval.quantity.scaler = Quantity::Foot; yylval.quantity.unitStr = yytext; return UNIT; // foot
"'" COUNTCHARS; yylval.quantity.scaler = Quantity::Foot; yylval.quantity.unitStr = yytext; return UNIT; // foot
"'" COUNTCHARS; yylval.quantity.scaler = Quantity::Foot; yylval.quantity.unitStr = yytext; return USUNIT; // foot
"thou" COUNTCHARS; yylval.quantity.scaler = Quantity::Thou; yylval.quantity.unitStr = yytext; return UNIT; // thou (in/1000)
"mil" COUNTCHARS; yylval.quantity.scaler = Quantity::Thou; yylval.quantity.unitStr = yytext; return UNIT; // mil (the thou in US)
"yd" COUNTCHARS; yylval.quantity.scaler = Quantity::Yard; yylval.quantity.unitStr = yytext; return UNIT; // yard

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,9 @@
/* A Bison parser, made by GNU Bison 3.0.4. */
/* A Bison parser, made by GNU Bison 3.8.2. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
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
@@ -15,7 +16,7 @@
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, see <http://www.gnu.org/licenses/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -30,6 +31,10 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
especially those whose name start with YY_ or yy_. They are
private implementation details that can be changed or removed. */
#ifndef YY_YY_EXPRESSIONPARSER_TAB_H_INCLUDED
# define YY_YY_EXPRESSIONPARSER_TAB_H_INCLUDED
/* Debug traces. */
@@ -40,35 +45,41 @@
extern int yydebug;
#endif
/* Token type. */
/* Token kinds. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
FUNC = 258,
ONE = 259,
NUM = 260,
IDENTIFIER = 261,
UNIT = 262,
INTEGER = 263,
CONSTANT = 264,
CELLADDRESS = 265,
EQ = 266,
NEQ = 267,
LT = 268,
GT = 269,
GTE = 270,
LTE = 271,
STRING = 272,
MINUSSIGN = 273,
PROPERTY_REF = 274,
DOCUMENT = 275,
OBJECT = 276,
EXPONENT = 277,
NUM_AND_UNIT = 278,
NEG = 279,
POS = 280
YYEMPTY = -2,
YYEOF = 0, /* "end of file" */
YYerror = 256, /* error */
YYUNDEF = 257, /* "invalid token" */
FUNC = 258, /* FUNC */
ONE = 259, /* ONE */
NUM = 260, /* NUM */
IDENTIFIER = 261, /* IDENTIFIER */
UNIT = 262, /* UNIT */
USUNIT = 263, /* USUNIT */
INTEGER = 264, /* INTEGER */
CONSTANT = 265, /* CONSTANT */
CELLADDRESS = 266, /* CELLADDRESS */
EQ = 267, /* EQ */
NEQ = 268, /* NEQ */
LT = 269, /* LT */
GT = 270, /* GT */
GTE = 271, /* GTE */
LTE = 272, /* LTE */
STRING = 273, /* STRING */
MINUSSIGN = 274, /* MINUSSIGN */
PROPERTY_REF = 275, /* PROPERTY_REF */
DOCUMENT = 276, /* DOCUMENT */
OBJECT = 277, /* OBJECT */
EXPONENT = 278, /* EXPONENT */
NUM_AND_UNIT = 279, /* NUM_AND_UNIT */
NEG = 280, /* NEG */
POS = 281 /* POS */
};
typedef enum yytokentype yytoken_kind_t;
#endif
/* Value type. */
@@ -76,6 +87,8 @@ extern int yydebug;
extern YYSTYPE yylval;
int yyparse (void);
#endif /* !YY_YY_EXPRESSIONPARSER_TAB_H_INCLUDED */

View File

@@ -40,7 +40,7 @@ std::stack<FunctionExpression::Function> functions; /**< Function
%token ONE
%token NUM
%token IDENTIFIER
%token UNIT
%token UNIT USUNIT
%token INTEGER
%token CONSTANT
%token CELLADDRESS
@@ -49,8 +49,8 @@ std::stack<FunctionExpression::Function> functions; /**< Function
%token DOCUMENT OBJECT
%token EXPONENT
%type <arguments> args
%type <expr> input exp unit_exp cond indexable
%type <quantity> UNIT
%type <expr> input unit_num us_building_unit other_unit exp unit_exp cond indexable
%type <quantity> UNIT USUNIT
%type <string> id_or_cell STRING IDENTIFIER CELLADDRESS
%type <ivalue> INTEGER
%type <string> PROPERTY_REF
@@ -79,28 +79,32 @@ std::stack<FunctionExpression::Function> functions; /**< Function
%destructor { std::vector<Expression*>::const_iterator i = $$.begin(); while (i != $$.end()) { delete *i; ++i; } } args
%start input
%%
input: exp { ScanResult = $1; valueExpression = true; }
| unit_exp { ScanResult = $1; unitExpression = true; }
input: exp { ScanResult = $1; valueExpression = true; }
| unit_exp { ScanResult = $1; unitExpression = true; }
;
exp: num { $$ = $1; }
| num unit_exp %prec NUM_AND_UNIT { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::UNIT, $2); }
unit_num: num unit_exp %prec NUM_AND_UNIT { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::UNIT, $2); }
| num us_building_unit num us_building_unit %prec NUM_AND_UNIT { $$ = new OperatorExpression(DocumentObject, new OperatorExpression(DocumentObject, $1, OperatorExpression::UNIT, $2), OperatorExpression::ADD, new OperatorExpression(DocumentObject, $3, OperatorExpression::UNIT, $4));}
;
exp: num { $$ = $1; }
| unit_num { $$ = $1; }
| STRING { $$ = new StringExpression(DocumentObject, $1); }
| identifier { $$ = new VariableExpression(DocumentObject, $1); }
| MINUSSIGN exp %prec NEG { $$ = new OperatorExpression(DocumentObject, $2, OperatorExpression::NEG, new NumberExpression(DocumentObject, Quantity(-1))); }
| '+' exp %prec POS { $$ = new OperatorExpression(DocumentObject, $2, OperatorExpression::POS, new NumberExpression(DocumentObject, Quantity(1))); }
| exp '+' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::ADD, $3); }
| exp '+' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::ADD, $3); }
| exp MINUSSIGN exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::SUB, $3); }
| exp '*' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::MUL, $3); }
| exp '/' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::DIV, $3); }
| exp '%' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::MOD, $3); }
| exp '*' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::MUL, $3); }
| exp '/' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::DIV, $3); }
| exp '%' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::MOD, $3); }
| exp '/' unit_exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::DIV, $3); }
| exp '^' exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::POW, $3); }
| indexable { $$ = $1; }
| FUNC args ')' { $$ = new FunctionExpression(DocumentObject, $1.first, std::move($1.second), $2); }
| indexable { $$ = $1; }
| FUNC args ')' { $$ = new FunctionExpression(DocumentObject, $1.first, std::move($1.second), $2);}
| cond '?' exp ':' exp { $$ = new ConditionalExpression(DocumentObject, $1, $3, $5); }
| '(' exp ')' { $$ = $2; }
;
@@ -130,7 +134,11 @@ cond: exp EQ exp { $$ = new OperatorExpression(Do
| '(' cond ')' { $$ = $2; }
;
unit_exp: UNIT { $$ = new UnitExpression(DocumentObject, $1.scaler, $1.unitStr ); }
us_building_unit: USUNIT { $$ = new UnitExpression(DocumentObject, $1.scaler, $1.unitStr ); }
other_unit: UNIT { $$ = new UnitExpression(DocumentObject, $1.scaler, $1.unitStr ); }
unit_exp: other_unit { $$ = $1; }
| us_building_unit { $$ = $1; }
| unit_exp '/' unit_exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::DIV, $3); }
| unit_exp '*' unit_exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::MUL, $3); }
| unit_exp '^' integer { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::POW, new NumberExpression(DocumentObject, Quantity((double)$3))); }

View File

@@ -9131,7 +9131,7 @@ COUNTCHARS; yylval.quantity.scaler = Quantity::Inch; yylval.quan
case 49:
YY_RULE_SETUP
#line 234 "ExpressionParser.l"
COUNTCHARS; yylval.quantity.scaler = Quantity::Inch; yylval.quantity.unitStr = yytext; return UNIT; // inch
COUNTCHARS; yylval.quantity.scaler = Quantity::Inch; yylval.quantity.unitStr = yytext; return USUNIT; // inch
YY_BREAK
case 50:
YY_RULE_SETUP
@@ -9141,7 +9141,7 @@ COUNTCHARS; yylval.quantity.scaler = Quantity::Foot; yylval.quan
case 51:
YY_RULE_SETUP
#line 236 "ExpressionParser.l"
COUNTCHARS; yylval.quantity.scaler = Quantity::Foot; yylval.quantity.unitStr = yytext; return UNIT; // foot
COUNTCHARS; yylval.quantity.scaler = Quantity::Foot; yylval.quantity.unitStr = yytext; return USUNIT; // foot
YY_BREAK
case 52:
YY_RULE_SETUP