FreeCAD

Форк
0
/
ExpressionParser.y 
231 строка · 15.2 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2010 Jürgen Riegel <FreeCAD@juergen-riegel.net>         *
3
 *   Copyright (c) 2015 Eivind Kvedalen <eivind@kvedalen.name>             *
4
 *                                                                         *
5
 *   This file is part of the FreeCAD CAx development system.              *
6
 *                                                                         *
7
 *   This library is free software; you can redistribute it and/or         *
8
 *   modify it under the terms of the GNU Library General Public           *
9
 *   License as published by the Free Software Foundation; either          *
10
 *   version 2 of the License, or (at your option) any later version.      *
11
 *                                                                         *
12
 *   This library  is distributed in the hope that it will be useful,      *
13
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
14
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
15
 *   GNU Library General Public License for more details.                  *
16
 *                                                                         *
17
 *   You should have received a copy of the GNU Library General Public     *
18
 *   License along with this library; see the file COPYING.LIB. If not,    *
19
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
20
 *   Suite 330, Boston, MA  02111-1307, USA                                *
21
 *                                                                         *
22
 ***************************************************************************/
23

24
/* Parser for the FreeCAD Units language                     */
25
/* Represents the many different ways we can access our data */
26

27

28
%{
29

30
#define YYSTYPE App::ExpressionParser::semantic_type
31

32
std::stack<FunctionExpression::Function> functions;                /**< Function identifier */
33

34
       //#define YYSTYPE yystype
35
       #define yyparse ExpressionParser_yyparse
36
       #define yyerror ExpressionParser_yyerror
37
%}
38

39
     %token FUNC
40
     %token ONE
41
     %token NUM
42
     %token IDENTIFIER
43
     %token UNIT USUNIT
44
     %token INTEGER
45
     %token CONSTANT
46
     %token CELLADDRESS
47
     %token EQ NEQ LT GT GTE LTE
48
     %token STRING MINUSSIGN PROPERTY_REF
49
     %token DOCUMENT OBJECT
50
     %token EXPONENT
51
     %type <arguments> args
52
     %type <expr> input unit_num us_building_unit other_unit exp unit_exp cond indexable
53
     %type <quantity> UNIT USUNIT
54
     %type <string> id_or_cell STRING IDENTIFIER CELLADDRESS
55
     %type <ivalue> INTEGER
56
     %type <string> PROPERTY_REF
57
     %type <fvalue> ONE
58
     %type <fvalue> NUM
59
     %type <constant> CONSTANT
60
     %type <expr> num
61
     %type <expr> range
62
     %type <path> identifier iden
63
     %type <component> indexer
64
     %type <func> FUNC
65
     %type <string_or_identifier> document
66
     %type <string_or_identifier> object
67
     %type <ivalue> integer
68
     %precedence EQ NEQ LT GT GTE LTE
69
     %precedence ':'
70
     %left MINUSSIGN '+'
71
     %left '*' '/' '%'
72
     %precedence NUM_AND_UNIT
73
     %left '^'
74
     %precedence NEG
75
     %precedence POS
76

77
%destructor { delete $$; } num range exp cond unit_exp indexable
78
%destructor { delete $$; } <component>
79
%destructor { std::vector<Expression*>::const_iterator i = $$.begin(); while (i != $$.end()) { delete *i; ++i; } } args
80

81
%start input
82
%%
83

84

85
input:     exp                                  { ScanResult = $1; valueExpression = true;                                        }
86
     |     unit_exp                             { ScanResult = $1; unitExpression = true;                                         }
87
     ;
88

89
unit_num: num unit_exp %prec NUM_AND_UNIT       { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::UNIT, $2);  } 
90
        | 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));}
91
        ;
92

93
exp:      num                                   { $$ = $1;                                                                        }
94
        | unit_num                              { $$ = $1;                                                                        }
95
        | STRING                                { $$ = new StringExpression(DocumentObject, $1);                                  }
96
        | identifier                            { $$ = new VariableExpression(DocumentObject, $1);                                }
97
        | MINUSSIGN exp %prec NEG               { $$ = new OperatorExpression(DocumentObject, $2, OperatorExpression::NEG, new NumberExpression(DocumentObject, Quantity(-1))); }
98
        | '+' exp %prec POS                     { $$ = new OperatorExpression(DocumentObject, $2, OperatorExpression::POS, new NumberExpression(DocumentObject, Quantity(1))); }
99
        | exp '+' exp                           { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::ADD, $3);   }
100
        | exp MINUSSIGN exp                     { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::SUB, $3);   }
101
        | exp '*' exp                           { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::MUL, $3);   }
102
        | exp '/' exp                           { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::DIV, $3);   }
103
        | exp '%' exp                           { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::MOD, $3);   }
104
        | exp '/' unit_exp                      { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::DIV, $3);   }
105
        | exp '^' exp                           { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::POW, $3);   }
106
        | indexable                             { $$ = $1;                                                                        }
107
        | FUNC  args ')'                        { $$ = new FunctionExpression(DocumentObject, $1.first, std::move($1.second), $2);}
108
        | cond '?' exp ':' exp                  { $$ = new ConditionalExpression(DocumentObject, $1, $3, $5);                     }
109
        | '(' exp ')'                           { $$ = $2; }
110
        ;
111

112
num:       ONE                                  { $$ = new NumberExpression(DocumentObject, Quantity($1));                        }
113
         | NUM                                  { $$ = new NumberExpression(DocumentObject, Quantity($1));                        }
114
         | INTEGER                              { $$ = new NumberExpression(DocumentObject, Quantity((double)$1));                }
115
         | CONSTANT                             { $$ = new ConstantExpression(DocumentObject, $1.name, Quantity($1.fvalue));      }
116

117
args: exp                                       { $$.push_back($1);                                                               }
118
    | range                                     { $$.push_back($1);                                                               }
119
    | args ',' exp                              { $1.push_back($3);  $$ = $1;                                                     }
120
    | args ';' exp                              { $1.push_back($3);  $$ = $1;                                                     }
121
    | args ',' range                            { $1.push_back($3);  $$ = $1;                                                     }
122
    | args ';' range                            { $1.push_back($3);  $$ = $1;                                                     }
123
    ;
124

125
range: id_or_cell ':' id_or_cell                { $$ = new RangeExpression(DocumentObject, $1, $3);                               }
126
     ;
127

128
cond: exp EQ exp                                { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::EQ, $3);    }
129
    | exp NEQ exp                               { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::NEQ, $3);   }
130
    | exp LT exp                                { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::LT, $3);    }
131
    | exp GT exp                                { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::GT, $3);    }
132
    | exp GTE exp                               { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::GTE, $3);   }
133
    | exp LTE exp                               { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::LTE, $3);   }
134
    | '(' cond ')'                              { $$ = $2; }
135
    ;
136

137
us_building_unit: USUNIT                        { $$ = new UnitExpression(DocumentObject, $1.scaler, $1.unitStr );                }
138
other_unit: UNIT                                { $$ = new UnitExpression(DocumentObject, $1.scaler, $1.unitStr );                }
139

140
unit_exp: other_unit                            { $$ = $1; }
141
        | us_building_unit                      { $$ = $1; }
142
        | unit_exp '/' unit_exp                 { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::DIV, $3);   }
143
        | unit_exp '*' unit_exp                 { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::MUL, $3);   }
144
        | unit_exp '^' integer                  { $$ = new OperatorExpression(DocumentObject, $1, OperatorExpression::POW, new NumberExpression(DocumentObject, Quantity((double)$3)));   }
145
        | 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))));   }
146
        | '(' unit_exp ')'                      { $$ = $2;                                                                        }
147
        ;
148

149
integer: INTEGER { $$ = $1; }
150
       | ONE { $$ = $1; }
151
       ;
152

153
id_or_cell
154
    : IDENTIFIER                            { $$ = std::move($1); }
155
    | CELLADDRESS                           { $$ = std::move($1); }
156
    ;
157

158
identifier
159
    : id_or_cell                            { $$ = ObjectIdentifier(DocumentObject); $$ << ObjectIdentifier::SimpleComponent($1); }
160
    | iden                                  { $$ = std::move($1); }
161
    ;
162

163
iden
164
    :  '.' STRING '.' id_or_cell            { /* Path to property of a sub-object of the current object*/
165
                                                $$ = ObjectIdentifier(DocumentObject,true);
166
                                                $$.setDocumentObjectName(DocumentObject,false,ObjectIdentifier::String(std::move($2),true),true);
167
                                                $$.addComponent(ObjectIdentifier::SimpleComponent($4));
168
                                            }
169
    | '.' id_or_cell                        { /* Path to property of the current document object */
170
                                                $$ = ObjectIdentifier(DocumentObject,true);
171
                                                $$.setDocumentObjectName(DocumentObject);
172
                                                $$.addComponent(ObjectIdentifier::SimpleComponent($2));
173
                                            }
174
    | object '.' STRING '.' id_or_cell      { /* Path to property of a sub-object */
175
                                                $$ = ObjectIdentifier(DocumentObject);
176
                                                $$.setDocumentObjectName(std::move($1), true, ObjectIdentifier::String(std::move($3),true),true);
177
                                                $$.addComponent(ObjectIdentifier::SimpleComponent($5));
178
                                                $$.resolveAmbiguity();
179
                                            }
180
    | object '.' id_or_cell                 { /* Path to property of a given document object */
181
                                                $$ = ObjectIdentifier(DocumentObject);
182
                                                $1.checkImport(DocumentObject);
183
                                                $$.addComponent(ObjectIdentifier::SimpleComponent($1));
184
                                                $$.addComponent(ObjectIdentifier::SimpleComponent($3));
185
                                                $$.resolveAmbiguity();
186
                                            }
187
    | document '#' object '.' id_or_cell    { /* Path to property from an external document, within a named document object */
188
                                                $$ = ObjectIdentifier(DocumentObject);
189
                                                $$.setDocumentName(std::move($1), true);
190
                                                $$.setDocumentObjectName(std::move($3), true);
191
                                                $$.addComponent(ObjectIdentifier::SimpleComponent($5));
192
                                                $$.resolveAmbiguity();
193
                                            }
194
    | document '#' object '.' STRING '.' id_or_cell
195
                                            {   $$ = ObjectIdentifier(DocumentObject);
196
                                                $$.setDocumentName(std::move($1), true);
197
                                                $$.setDocumentObjectName(std::move($3), true, ObjectIdentifier::String(std::move($5),true));
198
                                                $$.addComponent(ObjectIdentifier::SimpleComponent($7));
199
                                                $$.resolveAmbiguity();
200
                                            }
201
    | iden '.' IDENTIFIER                   { $$= std::move($1); $$.addComponent(ObjectIdentifier::SimpleComponent($3)); }
202
    ;
203

204
indexer
205
    : '[' exp ']'                           { $$ = Expression::createComponent($2);   }
206
    | '[' exp ':' ']'                       { $$ = Expression::createComponent($2,0,0,true); }
207
    | '[' ':' exp ']'                       { $$ = Expression::createComponent(0,$3); }
208
    | '[' ':' ':' exp ']'                   { $$ = Expression::createComponent(0,0,$4); }
209
    | '[' exp ':' exp ']'                   { $$ = Expression::createComponent($2,$4);}
210
    | '[' exp ':' ':' exp ']'               { $$ = Expression::createComponent($2,0,$5); }
211
    | '[' ':' exp ':' exp ']'               { $$ = Expression::createComponent(0,$3,$5); }
212
    | '[' exp ':' exp ':' exp ']'           { $$ = Expression::createComponent($2,$4,$6);}
213
    ;
214

215
indexable
216
    : identifier indexer                    { $$ = new VariableExpression(DocumentObject,$1); $$->addComponent($2); }
217
    | indexable indexer                     { $1->addComponent(std::move($2)); $$ = $1; }
218
    | indexable '.' IDENTIFIER              { $1->addComponent(Expression::createComponent($3)); $$ = $1; }
219
    ;
220

221
document
222
    : STRING                                { $$ = ObjectIdentifier::String(std::move($1), true); }
223
    | IDENTIFIER                            { $$ = ObjectIdentifier::String(std::move($1), false, true);}
224
    ;
225

226
object
227
    : STRING                                { $$ = ObjectIdentifier::String(std::move($1), true); }
228
    | id_or_cell                            { $$ = ObjectIdentifier::String(std::move($1), false);}
229
    ;
230

231
%%
232

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.