update expression grammar to handle parens around cond
This commit is contained in:
@@ -61,6 +61,7 @@ extern int column;
|
||||
%option noyywrap nounput
|
||||
|
||||
/* UTF-8 unicode regular expressions. */
|
||||
/* http://www.unicode.org/reports/tr44/#General_Category_Values */
|
||||
|
||||
Cc ([\x00-\x1f\x7f]|\xc2[\x80-\x9f])
|
||||
Cf (\xc2\xad|\xd8[\x80-\x85\x9c]|\xdb\x9d|\xdc\x8f|\xe1(\xa0\x8e)|\xe2(\x80[\x8b-\x8f\xaa-\xae]|\x81[\xa0-\xa4\xa6-\xaf])|\xef(\xbb\xbf|\xbf[\xb9-\xbb])|\xf0(\x91(\x82\xbd))|\xf3(\xa0(\x80\x81)))
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Description for bash script
|
||||
flex -olex.ExpressionParser.c < ExpressionParser.l
|
||||
bison -oExpressionParser.tab.c ExpressionParser.y
|
||||
#!/usr/bin/env sh
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
flex -v -olex.ExpressionParser.c ExpressionParser.l
|
||||
bison -d -v -Wall -oExpressionParser.tab.c ExpressionParser.y
|
||||
|
||||
@@ -36,7 +36,6 @@ std::stack<FunctionExpression::Function> functions; /**< Function
|
||||
#define yyerror ExpressionParser_yyerror
|
||||
%}
|
||||
|
||||
/* Bison declarations. */
|
||||
%token FUNC
|
||||
%token ONE
|
||||
%token NUM
|
||||
@@ -66,16 +65,14 @@ std::stack<FunctionExpression::Function> functions; /**< Function
|
||||
%type <string_or_identifier> document
|
||||
%type <string_or_identifier> object
|
||||
%type <ivalue> integer
|
||||
%left ONE NUM INTEGER CONSTANT
|
||||
%left EQ NEQ LT GT GTE LTE
|
||||
%left '?' ':'
|
||||
%precedence EQ NEQ LT GT GTE LTE
|
||||
%precedence ':'
|
||||
%left MINUSSIGN '+'
|
||||
%left '*' '/' '%'
|
||||
%precedence NUM_AND_UNIT
|
||||
%left '^' /* exponentiation */
|
||||
%left EXPONENT
|
||||
%left NEG /* negation--unary minus */
|
||||
%left POS /* unary plus */
|
||||
%left '^'
|
||||
%precedence NEG
|
||||
%precedence POS
|
||||
|
||||
%destructor { delete $$; } num range exp cond unit_exp indexable
|
||||
%destructor { delete $$; } <component>
|
||||
@@ -105,6 +102,7 @@ exp: num { $$ = $1;
|
||||
| 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)); }
|
||||
@@ -129,6 +127,7 @@ cond: exp EQ exp { $$ = new OperatorExpression(Do
|
||||
| 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; }
|
||||
;
|
||||
|
||||
unit_exp: UNIT { $$ = new UnitExpression(DocumentObject, $1.scaler, $1.unitStr ); }
|
||||
@@ -206,8 +205,7 @@ indexer
|
||||
;
|
||||
|
||||
indexable
|
||||
: '(' exp ')' { $$ = $2; }
|
||||
| identifier indexer { $$ = new VariableExpression(DocumentObject,$1); $$->addComponent($2); }
|
||||
: identifier indexer { $$ = new VariableExpression(DocumentObject,$1); $$->addComponent($2); }
|
||||
| indexable indexer { $1->addComponent(std::move($2)); $$ = $1; }
|
||||
| indexable '.' IDENTIFIER { $1->addComponent(Expression::createComponent($3)); $$ = $1; }
|
||||
;
|
||||
|
||||
@@ -46,7 +46,6 @@ class SpreadsheetCases(unittest.TestCase):
|
||||
def testAggregates(self):
|
||||
""" Test all aggregate functions """
|
||||
sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet')
|
||||
sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet')
|
||||
sheet.set('B13', '4')
|
||||
sheet.set('B14', '5')
|
||||
sheet.set('B15', '6')
|
||||
@@ -165,7 +164,6 @@ class SpreadsheetCases(unittest.TestCase):
|
||||
|
||||
def testFunctions(self):
|
||||
""" Test all built-in simple functions """
|
||||
doc = FreeCAD.newDocument()
|
||||
sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet')
|
||||
sheet.set('A1', '=cos(60)') # Cos
|
||||
sheet.set('B1', '=cos(60deg)')
|
||||
@@ -366,7 +364,6 @@ class SpreadsheetCases(unittest.TestCase):
|
||||
self.assertMostlyEqual(sheet.B27, l)
|
||||
self.assertTrue(sheet.C27.startswith(u'ERR: Units must be equal'))
|
||||
self.assertMostlyEqual(sheet.D27, Units.Quantity("3 mm"))
|
||||
FreeCAD.closeDocument(doc.Name)
|
||||
|
||||
def testRelationalOperators(self):
|
||||
""" Test relational operators """
|
||||
@@ -1442,6 +1439,15 @@ class SpreadsheetCases(unittest.TestCase):
|
||||
sheet.setAlias('A1', 'aliasOfEmptyCell')
|
||||
self.assertEqual(sheet.getCellFromAlias("aliasOfEmptyCell"),"A1")
|
||||
|
||||
def testParensAroundCondition(self):
|
||||
""" Parens around a condition should be accepted """
|
||||
sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet')
|
||||
|
||||
sheet.set('A1', '=(1 == 1) ? 1 : 0')
|
||||
self.doc.recompute()
|
||||
self.assertEqual(sheet.getContents('A1'), '=1 == 1 ? 1 : 0')
|
||||
self.assertEqual(sheet.A1, 1)
|
||||
|
||||
def tearDown(self):
|
||||
#closing doc
|
||||
FreeCAD.closeDocument(self.doc.Name)
|
||||
|
||||
Reference in New Issue
Block a user