App: Expression: rename lexer and parser files

Rename files according 7d233dc ("Gui: Rename generated lexer files
to match core naming pattern"). Note that C space errors (space
before tabs, spaces on blank lines, etc.) still need to be fixed
manually after regenerating lexer file.
This commit is contained in:
Ladislav Michl
2025-04-07 21:51:14 +02:00
committed by Benjamin Nauck
parent ce82b109d5
commit 3f025585dc
8 changed files with 648 additions and 665 deletions

View File

@@ -3544,13 +3544,13 @@ int ExpressionParserlex();
# pragma GCC diagnostic ignored "-Wfree-nonheap-object"
#endif
// Parser, defined in ExpressionParser.y
// Parser, defined in Expression.y
# define YYTOKENTYPE
#include "ExpressionParser.tab.c"
#include "Expression.tab.c"
#ifndef DOXYGEN_SHOULD_SKIP_THIS
// Scanner, defined in ExpressionParser.l
#include "lex.ExpressionParser.c"
// Scanner, defined in Expression.l
#include "Expression.lex.c"
#endif // DOXYGEN_SHOULD_SKIP_THIS
class StringBufferCleaner

View File

@@ -22,14 +22,7 @@
* *
***************************************************************************/
/* Lexer for the FreeCAD Expression language */
/* use this file to generate the file 'lex.ExpressionParser.c' using the program flex
* the command for this operation is:
* flex --outfile=lex.ExpressionParser.c ExpressionParser.l
* (flex for Windows is available here:
* https://sourceforge.net/projects/winflexbison/
* (you must then change 'flex' to 'win_flex' in the command)) */
/* Lexer for the FreeCAD Expression language */
/* This disables inclusion of unistd.h, which is not available under Visual C++
* on Win32. The C++ scanner uses STL streams instead. */
@@ -165,7 +158,7 @@ S ({S1}|{S2})
Z (\x20|\xc2\xa0|\xe1(\x9a\x80)|\xe2(\x80[\x80-\x8a\xa8-\xa9\xaf]|\x81\x9f)|\xe3(\x80\x80))
DIGIT [0-9]
EXPO [eE][-+]?[0-9]+
EXPO [eE][-+]?[0-9]+
%% /*** Filter language Part ***/
@@ -174,7 +167,7 @@ EXPO [eE][-+]?[0-9]+
\<\<(\\(.|\n)|[^\\>\n])*\>\> COUNTCHARS; yylval.string = unquote(yytext); return STRING;
[%+()=/*^,\.\{\}\[\]:;@\?#] COUNTCHARS; return *yytext;
[%+()=/*^,\.\{\}\[\]:;@\?#] COUNTCHARS; return *yytext;
"==" COUNTCHARS; return EQ;
"!=" COUNTCHARS; return NEQ;
@@ -332,9 +325,9 @@ EXPO [eE][-+]?[0-9]+
"rad" COUNTCHARS; yylval.quantity.scaler = Quantity::Radian; yylval.quantity.unitStr = yytext; return UNIT; // radian
"gon" COUNTCHARS; yylval.quantity.scaler = Quantity::Gon; yylval.quantity.unitStr = yytext; return UNIT; // gon
"M" COUNTCHARS; yylval.quantity.scaler = Quantity::AngMinute; yylval.quantity.unitStr = yytext; return UNIT; // angminute
"\xE2\x80\xB2" COUNTCHARS; yylval.quantity.scaler = Quantity::AngMinute; yylval.quantity.unitStr = yytext; return UNIT; // angminute U+2032 &prime; &#8242;
"\xE2\x80\xB2" COUNTCHARS; yylval.quantity.scaler = Quantity::AngMinute; yylval.quantity.unitStr = yytext; return UNIT; // angminute U+2032 &prime; &#8242;
"AS" COUNTCHARS; yylval.quantity.scaler = Quantity::AngSecond; yylval.quantity.unitStr = yytext; return UNIT; // angsecond
"\xE2\x80\xB3" COUNTCHARS; yylval.quantity.scaler = Quantity::AngSecond; yylval.quantity.unitStr = yytext; return UNIT; // angsecond U+2033 &Prime; &#8243; ″
"\xE2\x80\xB3" COUNTCHARS; yylval.quantity.scaler = Quantity::AngSecond; yylval.quantity.unitStr = yytext; return UNIT; // angsecond U+2033 &Prime; &#8243; ″
{DIGIT}*"."{DIGIT}+{EXPO}? COUNTCHARS; yylval.fvalue = num_change(yytext,'.',','); return yylval.fvalue == 1 ? ONE : NUM;
{DIGIT}*","{DIGIT}+{EXPO}? COUNTCHARS; yylval.fvalue = num_change(yytext,',','.'); return yylval.fvalue == 1 ? ONE : NUM;

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,4 @@
// clang-format off
/* A Bison parser, made by GNU Bison 3.8.2. */
/* Bison implementation for Yacc-like parsers in C
@@ -67,18 +68,16 @@
/* First part of user prologue. */
#line 28 "ExpressionParser.y"
#define YYSTYPE App::ExpressionParser::semantic_type
std::stack<FunctionExpression::Function> functions; /**< Function identifier */
//#define YYSTYPE yystype
#define yyparse ExpressionParser_yyparse
#define yyerror ExpressionParser_yyerror
#line 26 "Expression.y"
#line 82 "ExpressionParser.tab.c"
#define YYSTYPE App::ExpressionParser::semantic_type
std::stack<FunctionExpression::Function> functions; /**< Function identifier */
#define yyparse ExpressionParser_yyparse
#define yyerror ExpressionParser_yyerror
#line 80 "Expression.tab.c"
# ifndef YY_CAST
# ifdef __cplusplus
@@ -101,7 +100,7 @@ std::stack<FunctionExpression::Function> functions; /**< Function
# endif
# endif
#include "ExpressionParser.tab.h"
#include "Expression.tab.h"
/* Symbol kind. */
enum yysymbol_kind_t
{
@@ -555,14 +554,14 @@ static const yytype_int8 yytranslate[] =
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
0, 86, 86, 87, 90, 91, 94, 95, 96, 97,
98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
108, 109, 110, 113, 114, 115, 116, 118, 119, 120,
121, 122, 123, 126, 129, 130, 131, 132, 133, 134,
135, 138, 139, 141, 142, 143, 144, 145, 146, 147,
150, 151, 155, 156, 160, 161, 165, 170, 175, 181,
188, 195, 202, 206, 207, 208, 209, 210, 211, 212,
213, 217, 218, 219, 223, 224, 228, 229
0, 81, 81, 82, 85, 86, 89, 90, 91, 92,
93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
103, 104, 105, 108, 109, 110, 111, 113, 114, 115,
116, 117, 118, 121, 124, 125, 126, 127, 128, 129,
130, 133, 134, 136, 137, 138, 139, 140, 141, 142,
145, 146, 150, 151, 155, 156, 160, 165, 170, 176,
183, 190, 197, 201, 202, 203, 204, 205, 206, 207,
208, 212, 213, 214, 218, 219, 223, 224
};
#endif
@@ -1008,51 +1007,51 @@ yydestruct (const char *yymsg,
switch (yykind)
{
case YYSYMBOL_exp: /* exp */
#line 78 "ExpressionParser.y"
#line 73 "Expression.y"
{ delete ((*yyvaluep).expr); }
#line 1014 "ExpressionParser.tab.c"
#line 1012 "Expression.tab.c"
break;
case YYSYMBOL_num: /* num */
#line 78 "ExpressionParser.y"
#line 73 "Expression.y"
{ delete ((*yyvaluep).expr); }
#line 1020 "ExpressionParser.tab.c"
#line 1018 "Expression.tab.c"
break;
case YYSYMBOL_args: /* args */
#line 80 "ExpressionParser.y"
#line 75 "Expression.y"
{ std::vector<Expression*>::const_iterator i = ((*yyvaluep).arguments).begin(); while (i != ((*yyvaluep).arguments).end()) { delete *i; ++i; } }
#line 1026 "ExpressionParser.tab.c"
#line 1024 "Expression.tab.c"
break;
case YYSYMBOL_range: /* range */
#line 78 "ExpressionParser.y"
#line 73 "Expression.y"
{ delete ((*yyvaluep).expr); }
#line 1032 "ExpressionParser.tab.c"
#line 1030 "Expression.tab.c"
break;
case YYSYMBOL_cond: /* cond */
#line 78 "ExpressionParser.y"
#line 73 "Expression.y"
{ delete ((*yyvaluep).expr); }
#line 1038 "ExpressionParser.tab.c"
#line 1036 "Expression.tab.c"
break;
case YYSYMBOL_unit_exp: /* unit_exp */
#line 78 "ExpressionParser.y"
#line 73 "Expression.y"
{ delete ((*yyvaluep).expr); }
#line 1044 "ExpressionParser.tab.c"
#line 1042 "Expression.tab.c"
break;
case YYSYMBOL_indexer: /* indexer */
#line 79 "ExpressionParser.y"
#line 74 "Expression.y"
{ delete ((*yyvaluep).component); }
#line 1050 "ExpressionParser.tab.c"
#line 1048 "Expression.tab.c"
break;
case YYSYMBOL_indexable: /* indexable */
#line 78 "ExpressionParser.y"
#line 73 "Expression.y"
{ delete ((*yyvaluep).expr); }
#line 1056 "ExpressionParser.tab.c"
#line 1054 "Expression.tab.c"
break;
default:
@@ -1320,362 +1319,362 @@ yyreduce:
switch (yyn)
{
case 2: /* input: exp */
#line 86 "ExpressionParser.y"
#line 81 "Expression.y"
{ ScanResult = (yyvsp[0].expr); valueExpression = true; }
#line 1326 "ExpressionParser.tab.c"
#line 1324 "Expression.tab.c"
break;
case 3: /* input: unit_exp */
#line 87 "ExpressionParser.y"
#line 82 "Expression.y"
{ ScanResult = (yyvsp[0].expr); unitExpression = true; }
#line 1332 "ExpressionParser.tab.c"
#line 1330 "Expression.tab.c"
break;
case 4: /* unit_num: num unit_exp */
#line 90 "ExpressionParser.y"
#line 85 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-1].expr), OperatorExpression::UNIT, (yyvsp[0].expr)); }
#line 1338 "ExpressionParser.tab.c"
#line 1336 "Expression.tab.c"
break;
case 5: /* unit_num: num us_building_unit num us_building_unit */
#line 91 "ExpressionParser.y"
#line 86 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, new OperatorExpression(DocumentObject, (yyvsp[-3].expr), OperatorExpression::UNIT, (yyvsp[-2].expr)), OperatorExpression::ADD, new OperatorExpression(DocumentObject, (yyvsp[-1].expr), OperatorExpression::UNIT, (yyvsp[0].expr)));}
#line 1344 "ExpressionParser.tab.c"
#line 1342 "Expression.tab.c"
break;
case 6: /* exp: num */
#line 94 "ExpressionParser.y"
#line 89 "Expression.y"
{ (yyval.expr) = (yyvsp[0].expr); }
#line 1350 "ExpressionParser.tab.c"
#line 1348 "Expression.tab.c"
break;
case 7: /* exp: unit_num */
#line 95 "ExpressionParser.y"
#line 90 "Expression.y"
{ (yyval.expr) = (yyvsp[0].expr); }
#line 1356 "ExpressionParser.tab.c"
#line 1354 "Expression.tab.c"
break;
case 8: /* exp: STRING */
#line 96 "ExpressionParser.y"
#line 91 "Expression.y"
{ (yyval.expr) = new StringExpression(DocumentObject, (yyvsp[0].string)); }
#line 1362 "ExpressionParser.tab.c"
#line 1360 "Expression.tab.c"
break;
case 9: /* exp: identifier */
#line 97 "ExpressionParser.y"
#line 92 "Expression.y"
{ (yyval.expr) = new VariableExpression(DocumentObject, (yyvsp[0].path)); }
#line 1368 "ExpressionParser.tab.c"
#line 1366 "Expression.tab.c"
break;
case 10: /* exp: MINUSSIGN exp */
#line 98 "ExpressionParser.y"
#line 93 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[0].expr), OperatorExpression::NEG, new NumberExpression(DocumentObject, Quantity(-1))); }
#line 1374 "ExpressionParser.tab.c"
#line 1372 "Expression.tab.c"
break;
case 11: /* exp: '+' exp */
#line 99 "ExpressionParser.y"
#line 94 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[0].expr), OperatorExpression::POS, new NumberExpression(DocumentObject, Quantity(1))); }
#line 1380 "ExpressionParser.tab.c"
#line 1378 "Expression.tab.c"
break;
case 12: /* exp: exp '+' exp */
#line 100 "ExpressionParser.y"
#line 95 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::ADD, (yyvsp[0].expr)); }
#line 1386 "ExpressionParser.tab.c"
#line 1384 "Expression.tab.c"
break;
case 13: /* exp: exp MINUSSIGN exp */
#line 101 "ExpressionParser.y"
#line 96 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::SUB, (yyvsp[0].expr)); }
#line 1392 "ExpressionParser.tab.c"
#line 1390 "Expression.tab.c"
break;
case 14: /* exp: exp '*' exp */
#line 102 "ExpressionParser.y"
#line 97 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::MUL, (yyvsp[0].expr)); }
#line 1398 "ExpressionParser.tab.c"
#line 1396 "Expression.tab.c"
break;
case 15: /* exp: exp '/' exp */
#line 103 "ExpressionParser.y"
#line 98 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::DIV, (yyvsp[0].expr)); }
#line 1404 "ExpressionParser.tab.c"
#line 1402 "Expression.tab.c"
break;
case 16: /* exp: exp '%' exp */
#line 104 "ExpressionParser.y"
#line 99 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::MOD, (yyvsp[0].expr)); }
#line 1410 "ExpressionParser.tab.c"
#line 1408 "Expression.tab.c"
break;
case 17: /* exp: exp '/' unit_exp */
#line 105 "ExpressionParser.y"
#line 100 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::DIV, (yyvsp[0].expr)); }
#line 1416 "ExpressionParser.tab.c"
#line 1414 "Expression.tab.c"
break;
case 18: /* exp: exp '^' exp */
#line 106 "ExpressionParser.y"
#line 101 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::POW, (yyvsp[0].expr)); }
#line 1422 "ExpressionParser.tab.c"
#line 1420 "Expression.tab.c"
break;
case 19: /* exp: indexable */
#line 107 "ExpressionParser.y"
#line 102 "Expression.y"
{ (yyval.expr) = (yyvsp[0].expr); }
#line 1428 "ExpressionParser.tab.c"
#line 1426 "Expression.tab.c"
break;
case 20: /* exp: FUNC args ')' */
#line 108 "ExpressionParser.y"
#line 103 "Expression.y"
{ (yyval.expr) = new FunctionExpression(DocumentObject, (yyvsp[-2].func).first, std::move((yyvsp[-2].func).second), (yyvsp[-1].arguments));}
#line 1434 "ExpressionParser.tab.c"
#line 1432 "Expression.tab.c"
break;
case 21: /* exp: cond '?' exp ':' exp */
#line 109 "ExpressionParser.y"
#line 104 "Expression.y"
{ (yyval.expr) = new ConditionalExpression(DocumentObject, (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].expr)); }
#line 1440 "ExpressionParser.tab.c"
#line 1438 "Expression.tab.c"
break;
case 22: /* exp: '(' exp ')' */
#line 110 "ExpressionParser.y"
#line 105 "Expression.y"
{ (yyval.expr) = (yyvsp[-1].expr); }
#line 1446 "ExpressionParser.tab.c"
#line 1444 "Expression.tab.c"
break;
case 23: /* num: ONE */
#line 113 "ExpressionParser.y"
#line 108 "Expression.y"
{ (yyval.expr) = new NumberExpression(DocumentObject, Quantity((yyvsp[0].fvalue))); }
#line 1452 "ExpressionParser.tab.c"
#line 1450 "Expression.tab.c"
break;
case 24: /* num: NUM */
#line 114 "ExpressionParser.y"
#line 109 "Expression.y"
{ (yyval.expr) = new NumberExpression(DocumentObject, Quantity((yyvsp[0].fvalue))); }
#line 1458 "ExpressionParser.tab.c"
#line 1456 "Expression.tab.c"
break;
case 25: /* num: INTEGER */
#line 115 "ExpressionParser.y"
#line 110 "Expression.y"
{ (yyval.expr) = new NumberExpression(DocumentObject, Quantity((double)(yyvsp[0].ivalue))); }
#line 1464 "ExpressionParser.tab.c"
#line 1462 "Expression.tab.c"
break;
case 26: /* num: CONSTANT */
#line 116 "ExpressionParser.y"
#line 111 "Expression.y"
{ (yyval.expr) = new ConstantExpression(DocumentObject, (yyvsp[0].constant).name, Quantity((yyvsp[0].constant).fvalue)); }
#line 1470 "ExpressionParser.tab.c"
#line 1468 "Expression.tab.c"
break;
case 27: /* args: exp */
#line 118 "ExpressionParser.y"
#line 113 "Expression.y"
{ (yyval.arguments).push_back((yyvsp[0].expr)); }
#line 1476 "ExpressionParser.tab.c"
#line 1474 "Expression.tab.c"
break;
case 28: /* args: range */
#line 119 "ExpressionParser.y"
#line 114 "Expression.y"
{ (yyval.arguments).push_back((yyvsp[0].expr)); }
#line 1482 "ExpressionParser.tab.c"
#line 1480 "Expression.tab.c"
break;
case 29: /* args: args ',' exp */
#line 120 "ExpressionParser.y"
#line 115 "Expression.y"
{ (yyvsp[-2].arguments).push_back((yyvsp[0].expr)); (yyval.arguments) = (yyvsp[-2].arguments); }
#line 1488 "ExpressionParser.tab.c"
#line 1486 "Expression.tab.c"
break;
case 30: /* args: args ';' exp */
#line 121 "ExpressionParser.y"
#line 116 "Expression.y"
{ (yyvsp[-2].arguments).push_back((yyvsp[0].expr)); (yyval.arguments) = (yyvsp[-2].arguments); }
#line 1494 "ExpressionParser.tab.c"
#line 1492 "Expression.tab.c"
break;
case 31: /* args: args ',' range */
#line 122 "ExpressionParser.y"
#line 117 "Expression.y"
{ (yyvsp[-2].arguments).push_back((yyvsp[0].expr)); (yyval.arguments) = (yyvsp[-2].arguments); }
#line 1500 "ExpressionParser.tab.c"
#line 1498 "Expression.tab.c"
break;
case 32: /* args: args ';' range */
#line 123 "ExpressionParser.y"
#line 118 "Expression.y"
{ (yyvsp[-2].arguments).push_back((yyvsp[0].expr)); (yyval.arguments) = (yyvsp[-2].arguments); }
#line 1506 "ExpressionParser.tab.c"
#line 1504 "Expression.tab.c"
break;
case 33: /* range: id_or_cell ':' id_or_cell */
#line 126 "ExpressionParser.y"
#line 121 "Expression.y"
{ (yyval.expr) = new RangeExpression(DocumentObject, (yyvsp[-2].string), (yyvsp[0].string)); }
#line 1512 "ExpressionParser.tab.c"
#line 1510 "Expression.tab.c"
break;
case 34: /* cond: exp EQ exp */
#line 129 "ExpressionParser.y"
#line 124 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::EQ, (yyvsp[0].expr)); }
#line 1518 "ExpressionParser.tab.c"
#line 1516 "Expression.tab.c"
break;
case 35: /* cond: exp NEQ exp */
#line 130 "ExpressionParser.y"
#line 125 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::NEQ, (yyvsp[0].expr)); }
#line 1524 "ExpressionParser.tab.c"
#line 1522 "Expression.tab.c"
break;
case 36: /* cond: exp LT exp */
#line 131 "ExpressionParser.y"
#line 126 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::LT, (yyvsp[0].expr)); }
#line 1530 "ExpressionParser.tab.c"
#line 1528 "Expression.tab.c"
break;
case 37: /* cond: exp GT exp */
#line 132 "ExpressionParser.y"
#line 127 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::GT, (yyvsp[0].expr)); }
#line 1536 "ExpressionParser.tab.c"
#line 1534 "Expression.tab.c"
break;
case 38: /* cond: exp GTE exp */
#line 133 "ExpressionParser.y"
#line 128 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::GTE, (yyvsp[0].expr)); }
#line 1542 "ExpressionParser.tab.c"
#line 1540 "Expression.tab.c"
break;
case 39: /* cond: exp LTE exp */
#line 134 "ExpressionParser.y"
#line 129 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::LTE, (yyvsp[0].expr)); }
#line 1548 "ExpressionParser.tab.c"
#line 1546 "Expression.tab.c"
break;
case 40: /* cond: '(' cond ')' */
#line 135 "ExpressionParser.y"
#line 130 "Expression.y"
{ (yyval.expr) = (yyvsp[-1].expr); }
#line 1554 "ExpressionParser.tab.c"
#line 1552 "Expression.tab.c"
break;
case 41: /* us_building_unit: USUNIT */
#line 138 "ExpressionParser.y"
{ (yyval.expr) = new UnitExpression(DocumentObject, (yyvsp[0].quantity).scaler, (yyvsp[0].quantity).unitStr ); }
#line 1560 "ExpressionParser.tab.c"
#line 133 "Expression.y"
{ (yyval.expr) = new UnitExpression(DocumentObject, (yyvsp[0].quantity).scaler, (yyvsp[0].quantity).unitStr ); }
#line 1558 "Expression.tab.c"
break;
case 42: /* other_unit: UNIT */
#line 139 "ExpressionParser.y"
{ (yyval.expr) = new UnitExpression(DocumentObject, (yyvsp[0].quantity).scaler, (yyvsp[0].quantity).unitStr ); }
#line 1566 "ExpressionParser.tab.c"
#line 134 "Expression.y"
{ (yyval.expr) = new UnitExpression(DocumentObject, (yyvsp[0].quantity).scaler, (yyvsp[0].quantity).unitStr ); }
#line 1564 "Expression.tab.c"
break;
case 43: /* unit_exp: other_unit */
#line 141 "ExpressionParser.y"
#line 136 "Expression.y"
{ (yyval.expr) = (yyvsp[0].expr); }
#line 1572 "ExpressionParser.tab.c"
#line 1570 "Expression.tab.c"
break;
case 44: /* unit_exp: us_building_unit */
#line 142 "ExpressionParser.y"
#line 137 "Expression.y"
{ (yyval.expr) = (yyvsp[0].expr); }
#line 1578 "ExpressionParser.tab.c"
#line 1576 "Expression.tab.c"
break;
case 45: /* unit_exp: unit_exp '/' unit_exp */
#line 143 "ExpressionParser.y"
#line 138 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::DIV, (yyvsp[0].expr)); }
#line 1584 "ExpressionParser.tab.c"
#line 1582 "Expression.tab.c"
break;
case 46: /* unit_exp: unit_exp '*' unit_exp */
#line 144 "ExpressionParser.y"
#line 139 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::MUL, (yyvsp[0].expr)); }
#line 1590 "ExpressionParser.tab.c"
#line 1588 "Expression.tab.c"
break;
case 47: /* unit_exp: unit_exp '^' integer */
#line 145 "ExpressionParser.y"
#line 140 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-2].expr), OperatorExpression::POW, new NumberExpression(DocumentObject, Quantity((double)(yyvsp[0].ivalue)))); }
#line 1596 "ExpressionParser.tab.c"
#line 1594 "Expression.tab.c"
break;
case 48: /* unit_exp: unit_exp '^' MINUSSIGN integer */
#line 146 "ExpressionParser.y"
#line 141 "Expression.y"
{ (yyval.expr) = new OperatorExpression(DocumentObject, (yyvsp[-3].expr), OperatorExpression::POW, new OperatorExpression(DocumentObject, new NumberExpression(DocumentObject, Quantity((double)(yyvsp[0].ivalue))), OperatorExpression::NEG, new NumberExpression(DocumentObject, Quantity(-1)))); }
#line 1602 "ExpressionParser.tab.c"
#line 1600 "Expression.tab.c"
break;
case 49: /* unit_exp: '(' unit_exp ')' */
#line 147 "ExpressionParser.y"
#line 142 "Expression.y"
{ (yyval.expr) = (yyvsp[-1].expr); }
#line 1608 "ExpressionParser.tab.c"
#line 1606 "Expression.tab.c"
break;
case 50: /* integer: INTEGER */
#line 150 "ExpressionParser.y"
#line 145 "Expression.y"
{ (yyval.ivalue) = (yyvsp[0].ivalue); }
#line 1614 "ExpressionParser.tab.c"
#line 1612 "Expression.tab.c"
break;
case 51: /* integer: ONE */
#line 151 "ExpressionParser.y"
#line 146 "Expression.y"
{ (yyval.ivalue) = (yyvsp[0].fvalue); }
#line 1620 "ExpressionParser.tab.c"
#line 1618 "Expression.tab.c"
break;
case 52: /* id_or_cell: IDENTIFIER */
#line 155 "ExpressionParser.y"
#line 150 "Expression.y"
{ (yyval.string) = std::move((yyvsp[0].string)); }
#line 1626 "ExpressionParser.tab.c"
#line 1624 "Expression.tab.c"
break;
case 53: /* id_or_cell: CELLADDRESS */
#line 156 "ExpressionParser.y"
#line 151 "Expression.y"
{ (yyval.string) = std::move((yyvsp[0].string)); }
#line 1632 "ExpressionParser.tab.c"
#line 1630 "Expression.tab.c"
break;
case 54: /* identifier: id_or_cell */
#line 160 "ExpressionParser.y"
#line 155 "Expression.y"
{ (yyval.path) = ObjectIdentifier(DocumentObject); (yyval.path) << ObjectIdentifier::SimpleComponent((yyvsp[0].string)); }
#line 1638 "ExpressionParser.tab.c"
#line 1636 "Expression.tab.c"
break;
case 55: /* identifier: iden */
#line 161 "ExpressionParser.y"
#line 156 "Expression.y"
{ (yyval.path) = std::move((yyvsp[0].path)); }
#line 1644 "ExpressionParser.tab.c"
#line 1642 "Expression.tab.c"
break;
case 56: /* iden: '.' STRING '.' id_or_cell */
#line 165 "ExpressionParser.y"
#line 160 "Expression.y"
{ /* Path to property of a sub-object of the current object*/
(yyval.path) = ObjectIdentifier(DocumentObject,true);
(yyval.path).setDocumentObjectName(DocumentObject,false,ObjectIdentifier::String(std::move((yyvsp[-2].string)),true),true);
(yyval.path).addComponent(ObjectIdentifier::SimpleComponent((yyvsp[0].string)));
}
#line 1654 "ExpressionParser.tab.c"
#line 1652 "Expression.tab.c"
break;
case 57: /* iden: '.' id_or_cell */
#line 170 "ExpressionParser.y"
#line 165 "Expression.y"
{ /* Path to property of the current document object */
(yyval.path) = ObjectIdentifier(DocumentObject,true);
(yyval.path).setDocumentObjectName(DocumentObject);
(yyval.path).addComponent(ObjectIdentifier::SimpleComponent((yyvsp[0].string)));
}
#line 1664 "ExpressionParser.tab.c"
#line 1662 "Expression.tab.c"
break;
case 58: /* iden: object '.' STRING '.' id_or_cell */
#line 175 "ExpressionParser.y"
#line 170 "Expression.y"
{ /* Path to property of a sub-object */
(yyval.path) = ObjectIdentifier(DocumentObject);
(yyval.path).setDocumentObjectName(std::move((yyvsp[-4].string_or_identifier)), true, ObjectIdentifier::String(std::move((yyvsp[-2].string)),true),true);
(yyval.path).addComponent(ObjectIdentifier::SimpleComponent((yyvsp[0].string)));
(yyval.path).resolveAmbiguity();
}
#line 1675 "ExpressionParser.tab.c"
#line 1673 "Expression.tab.c"
break;
case 59: /* iden: object '.' id_or_cell */
#line 181 "ExpressionParser.y"
#line 176 "Expression.y"
{ /* Path to property of a given document object */
(yyval.path) = ObjectIdentifier(DocumentObject);
(yyvsp[-2].string_or_identifier).checkImport(DocumentObject);
@@ -1683,11 +1682,11 @@ yyreduce:
(yyval.path).addComponent(ObjectIdentifier::SimpleComponent((yyvsp[0].string)));
(yyval.path).resolveAmbiguity();
}
#line 1687 "ExpressionParser.tab.c"
#line 1685 "Expression.tab.c"
break;
case 60: /* iden: document '#' object '.' id_or_cell */
#line 188 "ExpressionParser.y"
#line 183 "Expression.y"
{ /* Path to property from an external document, within a named document object */
(yyval.path) = ObjectIdentifier(DocumentObject);
(yyval.path).setDocumentName(std::move((yyvsp[-4].string_or_identifier)), true);
@@ -1695,118 +1694,118 @@ yyreduce:
(yyval.path).addComponent(ObjectIdentifier::SimpleComponent((yyvsp[0].string)));
(yyval.path).resolveAmbiguity();
}
#line 1699 "ExpressionParser.tab.c"
#line 1697 "Expression.tab.c"
break;
case 61: /* iden: document '#' object '.' STRING '.' id_or_cell */
#line 196 "ExpressionParser.y"
#line 191 "Expression.y"
{ (yyval.path) = ObjectIdentifier(DocumentObject);
(yyval.path).setDocumentName(std::move((yyvsp[-6].string_or_identifier)), true);
(yyval.path).setDocumentObjectName(std::move((yyvsp[-4].string_or_identifier)), true, ObjectIdentifier::String(std::move((yyvsp[-2].string)),true));
(yyval.path).addComponent(ObjectIdentifier::SimpleComponent((yyvsp[0].string)));
(yyval.path).resolveAmbiguity();
}
#line 1710 "ExpressionParser.tab.c"
#line 1708 "Expression.tab.c"
break;
case 62: /* iden: iden '.' IDENTIFIER */
#line 202 "ExpressionParser.y"
#line 197 "Expression.y"
{ (yyval.path)= std::move((yyvsp[-2].path)); (yyval.path).addComponent(ObjectIdentifier::SimpleComponent((yyvsp[0].string))); }
#line 1716 "ExpressionParser.tab.c"
#line 1714 "Expression.tab.c"
break;
case 63: /* indexer: '[' exp ']' */
#line 206 "ExpressionParser.y"
#line 201 "Expression.y"
{ (yyval.component) = Expression::createComponent((yyvsp[-1].expr)); }
#line 1722 "ExpressionParser.tab.c"
#line 1720 "Expression.tab.c"
break;
case 64: /* indexer: '[' exp ':' ']' */
#line 207 "ExpressionParser.y"
#line 202 "Expression.y"
{ (yyval.component) = Expression::createComponent((yyvsp[-2].expr),0,0,true); }
#line 1728 "ExpressionParser.tab.c"
#line 1726 "Expression.tab.c"
break;
case 65: /* indexer: '[' ':' exp ']' */
#line 208 "ExpressionParser.y"
#line 203 "Expression.y"
{ (yyval.component) = Expression::createComponent(0,(yyvsp[-1].expr)); }
#line 1734 "ExpressionParser.tab.c"
#line 1732 "Expression.tab.c"
break;
case 66: /* indexer: '[' ':' ':' exp ']' */
#line 209 "ExpressionParser.y"
#line 204 "Expression.y"
{ (yyval.component) = Expression::createComponent(0,0,(yyvsp[-1].expr)); }
#line 1740 "ExpressionParser.tab.c"
#line 1738 "Expression.tab.c"
break;
case 67: /* indexer: '[' exp ':' exp ']' */
#line 210 "ExpressionParser.y"
#line 205 "Expression.y"
{ (yyval.component) = Expression::createComponent((yyvsp[-3].expr),(yyvsp[-1].expr));}
#line 1746 "ExpressionParser.tab.c"
#line 1744 "Expression.tab.c"
break;
case 68: /* indexer: '[' exp ':' ':' exp ']' */
#line 211 "ExpressionParser.y"
#line 206 "Expression.y"
{ (yyval.component) = Expression::createComponent((yyvsp[-4].expr),0,(yyvsp[-1].expr)); }
#line 1752 "ExpressionParser.tab.c"
#line 1750 "Expression.tab.c"
break;
case 69: /* indexer: '[' ':' exp ':' exp ']' */
#line 212 "ExpressionParser.y"
#line 207 "Expression.y"
{ (yyval.component) = Expression::createComponent(0,(yyvsp[-3].expr),(yyvsp[-1].expr)); }
#line 1758 "ExpressionParser.tab.c"
#line 1756 "Expression.tab.c"
break;
case 70: /* indexer: '[' exp ':' exp ':' exp ']' */
#line 213 "ExpressionParser.y"
#line 208 "Expression.y"
{ (yyval.component) = Expression::createComponent((yyvsp[-5].expr),(yyvsp[-3].expr),(yyvsp[-1].expr));}
#line 1764 "ExpressionParser.tab.c"
#line 1762 "Expression.tab.c"
break;
case 71: /* indexable: identifier indexer */
#line 217 "ExpressionParser.y"
#line 212 "Expression.y"
{ (yyval.expr) = new VariableExpression(DocumentObject,(yyvsp[-1].path)); (yyval.expr)->addComponent((yyvsp[0].component)); }
#line 1770 "ExpressionParser.tab.c"
#line 1768 "Expression.tab.c"
break;
case 72: /* indexable: indexable indexer */
#line 218 "ExpressionParser.y"
#line 213 "Expression.y"
{ (yyvsp[-1].expr)->addComponent(std::move((yyvsp[0].component))); (yyval.expr) = (yyvsp[-1].expr); }
#line 1776 "ExpressionParser.tab.c"
#line 1774 "Expression.tab.c"
break;
case 73: /* indexable: indexable '.' IDENTIFIER */
#line 219 "ExpressionParser.y"
#line 214 "Expression.y"
{ (yyvsp[-2].expr)->addComponent(Expression::createComponent((yyvsp[0].string))); (yyval.expr) = (yyvsp[-2].expr); }
#line 1782 "ExpressionParser.tab.c"
#line 1780 "Expression.tab.c"
break;
case 74: /* document: STRING */
#line 223 "ExpressionParser.y"
#line 218 "Expression.y"
{ (yyval.string_or_identifier) = ObjectIdentifier::String(std::move((yyvsp[0].string)), true); }
#line 1788 "ExpressionParser.tab.c"
#line 1786 "Expression.tab.c"
break;
case 75: /* document: IDENTIFIER */
#line 224 "ExpressionParser.y"
#line 219 "Expression.y"
{ (yyval.string_or_identifier) = ObjectIdentifier::String(std::move((yyvsp[0].string)), false, true);}
#line 1794 "ExpressionParser.tab.c"
#line 1792 "Expression.tab.c"
break;
case 76: /* object: STRING */
#line 228 "ExpressionParser.y"
#line 223 "Expression.y"
{ (yyval.string_or_identifier) = ObjectIdentifier::String(std::move((yyvsp[0].string)), true); }
#line 1800 "ExpressionParser.tab.c"
#line 1798 "Expression.tab.c"
break;
case 77: /* object: id_or_cell */
#line 229 "ExpressionParser.y"
#line 224 "Expression.y"
{ (yyval.string_or_identifier) = ObjectIdentifier::String(std::move((yyvsp[0].string)), false);}
#line 1806 "ExpressionParser.tab.c"
#line 1804 "Expression.tab.c"
break;
#line 1810 "ExpressionParser.tab.c"
#line 1808 "Expression.tab.c"
default: break;
}
@@ -1999,5 +1998,4 @@ yyreturnlab:
return yyresult;
}
#line 232 "ExpressionParser.y"
#line 227 "Expression.y"

View File

@@ -35,8 +35,8 @@
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
#ifndef YY_YY_EXPRESSION_TAB_H_INCLUDED
# define YY_YY_EXPRESSION_TAB_H_INCLUDED
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
@@ -91,4 +91,4 @@ extern YYSTYPE yylval;
int yyparse (void);
#endif /* !YY_YY_EXPRESSIONPARSER_TAB_H_INCLUDED */
#endif /* !YY_YY_EXPRESSION_TAB_H_INCLUDED */

View File

@@ -1,231 +1,227 @@
/***************************************************************************
* Copyright (c) 2010 Jürgen Riegel <FreeCAD@juergen-riegel.net> *
* Copyright (c) 2015 Eivind Kvedalen <eivind@kvedalen.name> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
/* Parser for the FreeCAD Units language */
/* Represents the many different ways we can access our data */
%{
#define YYSTYPE App::ExpressionParser::semantic_type
std::stack<FunctionExpression::Function> functions; /**< Function identifier */
//#define YYSTYPE yystype
#define yyparse ExpressionParser_yyparse
#define yyerror ExpressionParser_yyerror
%}
%token FUNC
%token ONE
%token NUM
%token IDENTIFIER
%token UNIT USUNIT
%token INTEGER
%token CONSTANT
%token CELLADDRESS
%token EQ NEQ LT GT GTE LTE
%token STRING MINUSSIGN PROPERTY_REF
%token DOCUMENT OBJECT
%token EXPONENT
%type <arguments> args
%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
%type <fvalue> ONE
%type <fvalue> NUM
%type <constant> CONSTANT
%type <expr> num
%type <expr> range
%type <path> identifier iden
%type <component> indexer
%type <func> FUNC
%type <string_or_identifier> document
%type <string_or_identifier> object
%type <ivalue> integer
%precedence EQ NEQ LT GT GTE LTE
%precedence ':'
%left MINUSSIGN '+'
%left '*' '/' '%'
%precedence NUM_AND_UNIT
%left '^'
%precedence NEG
%precedence POS
%destructor { delete $$; } num range exp cond unit_exp indexable
%destructor { delete $$; } <component>
%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; }
;
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 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 '/' 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);}
| cond '?' exp ':' exp { $$ = new ConditionalExpression(DocumentObject, $1, $3, $5); }
| '(' exp ')' { $$ = $2; }
;
num: ONE { $$ = new NumberExpression(DocumentObject, Quantity($1)); }
| NUM { $$ = new NumberExpression(DocumentObject, Quantity($1)); }
| INTEGER { $$ = new NumberExpression(DocumentObject, Quantity((double)$1)); }
| CONSTANT { $$ = new ConstantExpression(DocumentObject, $1.name, Quantity($1.fvalue)); }
args: exp { $$.push_back($1); }
| range { $$.push_back($1); }
| args ',' exp { $1.push_back($3); $$ = $1; }
| args ';' exp { $1.push_back($3); $$ = $1; }
| args ',' range { $1.push_back($3); $$ = $1; }
| args ';' range { $1.push_back($3); $$ = $1; }
;
range: id_or_cell ':' id_or_cell { $$ = new RangeExpression(DocumentObject, $1, $3); }
;
cond: exp EQ exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::EQ, $3); }
| exp NEQ exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::NEQ, $3); }
| exp LT exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::LT, $3); }
| exp GT exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::GT, $3); }
| exp GTE exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::GTE, $3); }
| exp LTE exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::LTE, $3); }
| '(' cond ')' { $$ = $2; }
;
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))); }
| unit_exp '^' MINUSSIGN integer { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::POW, new OperatorExpression(DocumentObject, new NumberExpression(DocumentObject, Quantity((double)$4)), OperatorExpression::NEG, new NumberExpression(DocumentObject, Quantity(-1)))); }
| '(' unit_exp ')' { $$ = $2; }
;
integer: INTEGER { $$ = $1; }
| ONE { $$ = $1; }
;
id_or_cell
: IDENTIFIER { $$ = std::move($1); }
| CELLADDRESS { $$ = std::move($1); }
;
identifier
: id_or_cell { $$ = ObjectIdentifier(DocumentObject); $$ << ObjectIdentifier::SimpleComponent($1); }
| iden { $$ = std::move($1); }
;
iden
: '.' STRING '.' id_or_cell { /* Path to property of a sub-object of the current object*/
$$ = ObjectIdentifier(DocumentObject,true);
$$.setDocumentObjectName(DocumentObject,false,ObjectIdentifier::String(std::move($2),true),true);
$$.addComponent(ObjectIdentifier::SimpleComponent($4));
}
| '.' id_or_cell { /* Path to property of the current document object */
$$ = ObjectIdentifier(DocumentObject,true);
$$.setDocumentObjectName(DocumentObject);
$$.addComponent(ObjectIdentifier::SimpleComponent($2));
}
| object '.' STRING '.' id_or_cell { /* Path to property of a sub-object */
$$ = ObjectIdentifier(DocumentObject);
$$.setDocumentObjectName(std::move($1), true, ObjectIdentifier::String(std::move($3),true),true);
$$.addComponent(ObjectIdentifier::SimpleComponent($5));
$$.resolveAmbiguity();
}
| object '.' id_or_cell { /* Path to property of a given document object */
$$ = ObjectIdentifier(DocumentObject);
$1.checkImport(DocumentObject);
$$.addComponent(ObjectIdentifier::SimpleComponent($1));
$$.addComponent(ObjectIdentifier::SimpleComponent($3));
$$.resolveAmbiguity();
}
| document '#' object '.' id_or_cell { /* Path to property from an external document, within a named document object */
$$ = ObjectIdentifier(DocumentObject);
$$.setDocumentName(std::move($1), true);
$$.setDocumentObjectName(std::move($3), true);
$$.addComponent(ObjectIdentifier::SimpleComponent($5));
$$.resolveAmbiguity();
}
| document '#' object '.' STRING '.' id_or_cell
{ $$ = ObjectIdentifier(DocumentObject);
$$.setDocumentName(std::move($1), true);
$$.setDocumentObjectName(std::move($3), true, ObjectIdentifier::String(std::move($5),true));
$$.addComponent(ObjectIdentifier::SimpleComponent($7));
$$.resolveAmbiguity();
}
| iden '.' IDENTIFIER { $$= std::move($1); $$.addComponent(ObjectIdentifier::SimpleComponent($3)); }
;
indexer
: '[' exp ']' { $$ = Expression::createComponent($2); }
| '[' exp ':' ']' { $$ = Expression::createComponent($2,0,0,true); }
| '[' ':' exp ']' { $$ = Expression::createComponent(0,$3); }
| '[' ':' ':' exp ']' { $$ = Expression::createComponent(0,0,$4); }
| '[' exp ':' exp ']' { $$ = Expression::createComponent($2,$4);}
| '[' exp ':' ':' exp ']' { $$ = Expression::createComponent($2,0,$5); }
| '[' ':' exp ':' exp ']' { $$ = Expression::createComponent(0,$3,$5); }
| '[' exp ':' exp ':' exp ']' { $$ = Expression::createComponent($2,$4,$6);}
;
indexable
: identifier indexer { $$ = new VariableExpression(DocumentObject,$1); $$->addComponent($2); }
| indexable indexer { $1->addComponent(std::move($2)); $$ = $1; }
| indexable '.' IDENTIFIER { $1->addComponent(Expression::createComponent($3)); $$ = $1; }
;
document
: STRING { $$ = ObjectIdentifier::String(std::move($1), true); }
| IDENTIFIER { $$ = ObjectIdentifier::String(std::move($1), false, true);}
;
object
: STRING { $$ = ObjectIdentifier::String(std::move($1), true); }
| id_or_cell { $$ = ObjectIdentifier::String(std::move($1), false);}
;
%%
/***************************************************************************
* Copyright (c) 2010 Jürgen Riegel <FreeCAD@juergen-riegel.net> *
* Copyright (c) 2015 Eivind Kvedalen <eivind@kvedalen.name> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
/* Parser for the FreeCAD Expression language */
%{
#define YYSTYPE App::ExpressionParser::semantic_type
std::stack<FunctionExpression::Function> functions; /**< Function identifier */
#define yyparse ExpressionParser_yyparse
#define yyerror ExpressionParser_yyerror
%}
%token FUNC
%token ONE
%token NUM
%token IDENTIFIER
%token UNIT USUNIT
%token INTEGER
%token CONSTANT
%token CELLADDRESS
%token EQ NEQ LT GT GTE LTE
%token STRING MINUSSIGN PROPERTY_REF
%token DOCUMENT OBJECT
%token EXPONENT
%type <arguments> args
%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
%type <fvalue> ONE
%type <fvalue> NUM
%type <constant> CONSTANT
%type <expr> num
%type <expr> range
%type <path> identifier iden
%type <component> indexer
%type <func> FUNC
%type <string_or_identifier> document
%type <string_or_identifier> object
%type <ivalue> integer
%precedence EQ NEQ LT GT GTE LTE
%precedence ':'
%left MINUSSIGN '+'
%left '*' '/' '%'
%precedence NUM_AND_UNIT
%left '^'
%precedence NEG
%precedence POS
%destructor { delete $$; } num range exp cond unit_exp indexable
%destructor { delete $$; } <component>
%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; }
;
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 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 '/' 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);}
| cond '?' exp ':' exp { $$ = new ConditionalExpression(DocumentObject, $1, $3, $5); }
| '(' exp ')' { $$ = $2; }
;
num: ONE { $$ = new NumberExpression(DocumentObject, Quantity($1)); }
| NUM { $$ = new NumberExpression(DocumentObject, Quantity($1)); }
| INTEGER { $$ = new NumberExpression(DocumentObject, Quantity((double)$1)); }
| CONSTANT { $$ = new ConstantExpression(DocumentObject, $1.name, Quantity($1.fvalue)); }
args: exp { $$.push_back($1); }
| range { $$.push_back($1); }
| args ',' exp { $1.push_back($3); $$ = $1; }
| args ';' exp { $1.push_back($3); $$ = $1; }
| args ',' range { $1.push_back($3); $$ = $1; }
| args ';' range { $1.push_back($3); $$ = $1; }
;
range: id_or_cell ':' id_or_cell { $$ = new RangeExpression(DocumentObject, $1, $3); }
;
cond: exp EQ exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::EQ, $3); }
| exp NEQ exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::NEQ, $3); }
| exp LT exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::LT, $3); }
| exp GT exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::GT, $3); }
| exp GTE exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::GTE, $3); }
| exp LTE exp { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::LTE, $3); }
| '(' cond ')' { $$ = $2; }
;
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))); }
| unit_exp '^' MINUSSIGN integer { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::POW, new OperatorExpression(DocumentObject, new NumberExpression(DocumentObject, Quantity((double)$4)), OperatorExpression::NEG, new NumberExpression(DocumentObject, Quantity(-1)))); }
| '(' unit_exp ')' { $$ = $2; }
;
integer: INTEGER { $$ = $1; }
| ONE { $$ = $1; }
;
id_or_cell
: IDENTIFIER { $$ = std::move($1); }
| CELLADDRESS { $$ = std::move($1); }
;
identifier
: id_or_cell { $$ = ObjectIdentifier(DocumentObject); $$ << ObjectIdentifier::SimpleComponent($1); }
| iden { $$ = std::move($1); }
;
iden
: '.' STRING '.' id_or_cell { /* Path to property of a sub-object of the current object*/
$$ = ObjectIdentifier(DocumentObject,true);
$$.setDocumentObjectName(DocumentObject,false,ObjectIdentifier::String(std::move($2),true),true);
$$.addComponent(ObjectIdentifier::SimpleComponent($4));
}
| '.' id_or_cell { /* Path to property of the current document object */
$$ = ObjectIdentifier(DocumentObject,true);
$$.setDocumentObjectName(DocumentObject);
$$.addComponent(ObjectIdentifier::SimpleComponent($2));
}
| object '.' STRING '.' id_or_cell { /* Path to property of a sub-object */
$$ = ObjectIdentifier(DocumentObject);
$$.setDocumentObjectName(std::move($1), true, ObjectIdentifier::String(std::move($3),true),true);
$$.addComponent(ObjectIdentifier::SimpleComponent($5));
$$.resolveAmbiguity();
}
| object '.' id_or_cell { /* Path to property of a given document object */
$$ = ObjectIdentifier(DocumentObject);
$1.checkImport(DocumentObject);
$$.addComponent(ObjectIdentifier::SimpleComponent($1));
$$.addComponent(ObjectIdentifier::SimpleComponent($3));
$$.resolveAmbiguity();
}
| document '#' object '.' id_or_cell { /* Path to property from an external document, within a named document object */
$$ = ObjectIdentifier(DocumentObject);
$$.setDocumentName(std::move($1), true);
$$.setDocumentObjectName(std::move($3), true);
$$.addComponent(ObjectIdentifier::SimpleComponent($5));
$$.resolveAmbiguity();
}
| document '#' object '.' STRING '.' id_or_cell
{ $$ = ObjectIdentifier(DocumentObject);
$$.setDocumentName(std::move($1), true);
$$.setDocumentObjectName(std::move($3), true, ObjectIdentifier::String(std::move($5),true));
$$.addComponent(ObjectIdentifier::SimpleComponent($7));
$$.resolveAmbiguity();
}
| iden '.' IDENTIFIER { $$= std::move($1); $$.addComponent(ObjectIdentifier::SimpleComponent($3)); }
;
indexer
: '[' exp ']' { $$ = Expression::createComponent($2); }
| '[' exp ':' ']' { $$ = Expression::createComponent($2,0,0,true); }
| '[' ':' exp ']' { $$ = Expression::createComponent(0,$3); }
| '[' ':' ':' exp ']' { $$ = Expression::createComponent(0,0,$4); }
| '[' exp ':' exp ']' { $$ = Expression::createComponent($2,$4);}
| '[' exp ':' ':' exp ']' { $$ = Expression::createComponent($2,0,$5); }
| '[' ':' exp ':' exp ']' { $$ = Expression::createComponent(0,$3,$5); }
| '[' exp ':' exp ':' exp ']' { $$ = Expression::createComponent($2,$4,$6);}
;
indexable
: identifier indexer { $$ = new VariableExpression(DocumentObject,$1); $$->addComponent($2); }
| indexable indexer { $1->addComponent(std::move($2)); $$ = $1; }
| indexable '.' IDENTIFIER { $1->addComponent(Expression::createComponent($3)); $$ = $1; }
;
document
: STRING { $$ = ObjectIdentifier::String(std::move($1), true); }
| IDENTIFIER { $$ = ObjectIdentifier::String(std::move($1), false, true);}
;
object
: STRING { $$ = ObjectIdentifier::String(std::move($1), true); }
| id_or_cell { $$ = ObjectIdentifier::String(std::move($1), false);}
;
%%

View File

@@ -649,7 +649,7 @@ public:
};
#define YYSTYPE semantic_type
#include "ExpressionParser.tab.h"
#include "Expression.tab.h"
#undef YYTOKENTYPE
#undef YYSTYPE
#undef YYSTYPE_ISDECLARED

View File

@@ -1,6 +1,8 @@
#!/usr/bin/env sh
cd "$(dirname "$0")"
flex -v -olex.ExpressionParser.c ExpressionParser.l
bison -d -v -Wall -oExpressionParser.tab.c ExpressionParser.y
(cd "$(dirname "$0")" && \
flex -v -oExpression.lex.c Expression.l && \
bison -d -v -Wall -oExpression.tab.c Expression.y && \
sed -i '1s|^|// clang-format off\n|' Expression.tab.c && \
sed -i '1s|^|// clang-format off\n|' Expression.lex.c \
)