diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l index 6a159d4fe..547b8545f 100644 --- a/poincare/src/expression_lexer.l +++ b/poincare/src/expression_lexer.l @@ -23,7 +23,7 @@ * Those tokens (and the optional value that they can be attached) are defined * in the Bison grammar. To use those token definitions, we need to include the * header generated by Bison. - * Also, since some tokens can have an "Expression *" value attached, we'll + * Also, since some tokens can have an "Expression" value attached, we'll * need "Expression" to be defined before including that header. * We could use the '%code requires{}' directive to make sure that Expression is * well defined in the parser header, but this directive only comes in bison 3, @@ -80,82 +80,82 @@ using namespace Poincare; * refered to Pi symbols. This artefact leads to the following lexer rules * starting with \x. */ -(([0-9]*[.]?[0-9]+)|([0-9]+[.]?[0-9]*))(\x8d\-?[0-9]+)? { yylval->expression = Poincare::Number::ParseDigits(yytext, yyleng); return DIGITS; } -[A-Za-z] { yylval->expression = Poincare::Symbol(yytext[0]); return SYMBOL; } -M[0-9] { yylval->expression = Poincare::Symbol(Symbol::matrixSymbol(yytext[1])); return SYMBOL; } -u\(n\) { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::un); return SYMBOL; } -u\(n\+1\) { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::un1); return SYMBOL; } -v\(n\) { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::vn); return SYMBOL; } -v\(n\+1\) { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::vn1); return SYMBOL; } -u\_\{n\} { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::un); return SYMBOL; } -u\_\{n\+1\} { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::un1); return SYMBOL; } -v\_\{n\} { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::vn); return SYMBOL; } -v\_\{n\+1\} { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::vn1); return SYMBOL; } -V1 { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::V1); return SYMBOL; } -N1 { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::N1); return SYMBOL; } -V2 { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::V2); return SYMBOL; } -N2 { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::N2); return SYMBOL; } -V3 { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::V3); return SYMBOL; } -N3 { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::N3); return SYMBOL; } -X1 { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::X1); return SYMBOL; } -Y1 { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::Y1); return SYMBOL; } -X2 { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::X2); return SYMBOL; } -Y2 { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::Y2); return SYMBOL; } -X3 { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::X3); return SYMBOL; } -Y3 { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::Y3); return SYMBOL; } -acos { yylval->expression = ArcCosine(); return FUNCTION; } -acosh { yylval->expression = HyperbolicArcCosine(); return FUNCTION; } -abs { yylval->expression = AbsoluteValue(); return FUNCTION; } -ans { yylval->expression = Poincare::Symbol(Symbol::SpecialSymbols::Ans); return SYMBOL; } -arg { yylval->expression = ComplexArgument(); return FUNCTION; } -asin { yylval->expression = ArcSine(); return FUNCTION; } -asinh { yylval->expression = HyperbolicArcSine(); return FUNCTION; } -atan { yylval->expression = ArcTangent(); return FUNCTION; } -atanh { yylval->expression = HyperbolicArcTangent(); return FUNCTION; } -binomial { yylval->expression = BinomialCoefficient(); return FUNCTION; } -ceil { yylval->expression = Ceiling(); return FUNCTION; } -confidence { yylval->expression = ConfidenceInterval(); return FUNCTION; } -diff { yylval->expression = Derivative(); return FUNCTION; } -dim { yylval->expression = MatrixDimension(); return FUNCTION; } -conj { yylval->expression = Conjugate(); return FUNCTION; } -det { yylval->expression = Determinant(); return FUNCTION; } -cos { yylval->expression = Cosine(); return FUNCTION; } -cosh { yylval->expression = HyperbolicCosine(); return FUNCTION; } -factor { yylval->expression = Factor(); return FUNCTION; } -floor { yylval->expression = Floor(); return FUNCTION; } -frac { yylval->expression = FracPart(); return FUNCTION; } -gcd { yylval->expression = GreatCommonDivisor(); return FUNCTION; } -im { yylval->expression = ImaginaryPart(); return FUNCTION; } -int { yylval->expression = Integral(); return FUNCTION; } -inverse { yylval->expression = MatrixInverse(); return FUNCTION; } -lcm { yylval->expression = LeastCommonMultiple(); return FUNCTION; } -ln { yylval->expression = NaperianLogarithm(); return FUNCTION; } +(([0-9]*[.]?[0-9]+)|([0-9]+[.]?[0-9]*))(\x8d\-?[0-9]+)? { *yylval = Poincare::Number::ParseDigits(yytext, yyleng); return DIGITS; } +[A-Za-z] { *yylval = Poincare::Symbol(yytext[0]); return SYMBOL; } +M[0-9] { *yylval = Poincare::Symbol(Symbol::matrixSymbol(yytext[1])); return SYMBOL; } +u\(n\) { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::un); return SYMBOL; } +u\(n\+1\) { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::un1); return SYMBOL; } +v\(n\) { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::vn); return SYMBOL; } +v\(n\+1\) { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::vn1); return SYMBOL; } +u\_\{n\} { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::un); return SYMBOL; } +u\_\{n\+1\} { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::un1); return SYMBOL; } +v\_\{n\} { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::vn); return SYMBOL; } +v\_\{n\+1\} { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::vn1); return SYMBOL; } +V1 { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::V1); return SYMBOL; } +N1 { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::N1); return SYMBOL; } +V2 { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::V2); return SYMBOL; } +N2 { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::N2); return SYMBOL; } +V3 { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::V3); return SYMBOL; } +N3 { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::N3); return SYMBOL; } +X1 { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::X1); return SYMBOL; } +Y1 { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::Y1); return SYMBOL; } +X2 { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::X2); return SYMBOL; } +Y2 { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::Y2); return SYMBOL; } +X3 { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::X3); return SYMBOL; } +Y3 { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::Y3); return SYMBOL; } +acos { *yylval = ArcCosine(); return FUNCTION; } +acosh { *yylval = HyperbolicArcCosine(); return FUNCTION; } +abs { *yylval = AbsoluteValue(); return FUNCTION; } +ans { *yylval = Poincare::Symbol(Symbol::SpecialSymbols::Ans); return SYMBOL; } +arg { *yylval = ComplexArgument(); return FUNCTION; } +asin { *yylval = ArcSine(); return FUNCTION; } +asinh { *yylval = HyperbolicArcSine(); return FUNCTION; } +atan { *yylval = ArcTangent(); return FUNCTION; } +atanh { *yylval = HyperbolicArcTangent(); return FUNCTION; } +binomial { *yylval = BinomialCoefficient(); return FUNCTION; } +ceil { *yylval = Ceiling(); return FUNCTION; } +confidence { *yylval = ConfidenceInterval(); return FUNCTION; } +diff { *yylval = Derivative(); return FUNCTION; } +dim { *yylval = MatrixDimension(); return FUNCTION; } +conj { *yylval = Conjugate(); return FUNCTION; } +det { *yylval = Determinant(); return FUNCTION; } +cos { *yylval = Cosine(); return FUNCTION; } +cosh { *yylval = HyperbolicCosine(); return FUNCTION; } +factor { *yylval = Factor(); return FUNCTION; } +floor { *yylval = Floor(); return FUNCTION; } +frac { *yylval = FracPart(); return FUNCTION; } +gcd { *yylval = GreatCommonDivisor(); return FUNCTION; } +im { *yylval = ImaginaryPart(); return FUNCTION; } +int { *yylval = Integral(); return FUNCTION; } +inverse { *yylval = MatrixInverse(); return FUNCTION; } +lcm { *yylval = LeastCommonMultiple(); return FUNCTION; } +ln { *yylval = NaperianLogarithm(); return FUNCTION; } log { return LOGFUNCTION; } -permute { yylval->expression = PermuteCoefficient(); return FUNCTION; } -prediction95 { yylval->expression = PredictionInterval(); return FUNCTION; } -prediction { yylval->expression = SimplePredictionInterval(); return FUNCTION; } -product { yylval->expression = Product(); return FUNCTION; } -quo { yylval->expression = DivisionQuotient(); return FUNCTION; } -random { yylval->expression = Random(); return FUNCTION; } -randint { yylval->expression = Randint(); return FUNCTION; } -re { yylval->expression = RealPart(); return FUNCTION; } -rem { yylval->expression = DivisionRemainder(); return FUNCTION; } -root { yylval->expression = NthRoot(); return FUNCTION; } -round { yylval->expression = Round(); return FUNCTION; } -sin { yylval->expression = Sine(); return FUNCTION; } -sinh { yylval->expression = HyperbolicSine(); return FUNCTION; } -sum { yylval->expression = Sum(); return FUNCTION; } -tan { yylval->expression = Tangent(); return FUNCTION; } -tanh { yylval->expression = HyperbolicTangent(); return FUNCTION; } -trace { yylval->expression = MatrixTrace(); return FUNCTION; } -transpose { yylval->expression = MatrixTranspose(); return FUNCTION; } -undef { yylval->expression = Undefined(); return UNDEFINED; } -inf { yylval->expression = Undefined(); return UNDEFINED; } -\x8a { yylval->expression = Poincare::Symbol(yytext[0]); return SYMBOL; } -\x8c { yylval->expression = Poincare::Symbol(yytext[0]); return SYMBOL; } -\x8f { yylval->expression = Poincare::Symbol(yytext[0]); return SYMBOL; } +permute { *yylval = PermuteCoefficient(); return FUNCTION; } +prediction95 { *yylval = PredictionInterval(); return FUNCTION; } +prediction { *yylval = SimplePredictionInterval(); return FUNCTION; } +product { *yylval = Product(); return FUNCTION; } +quo { *yylval = DivisionQuotient(); return FUNCTION; } +random { *yylval = Random(); return FUNCTION; } +randint { *yylval = Randint(); return FUNCTION; } +re { *yylval = RealPart(); return FUNCTION; } +rem { *yylval = DivisionRemainder(); return FUNCTION; } +root { *yylval = NthRoot(); return FUNCTION; } +round { *yylval = Round(); return FUNCTION; } +sin { *yylval = Sine(); return FUNCTION; } +sinh { *yylval = HyperbolicSine(); return FUNCTION; } +sum { *yylval = Sum(); return FUNCTION; } +tan { *yylval = Tangent(); return FUNCTION; } +tanh { *yylval = HyperbolicTangent(); return FUNCTION; } +trace { *yylval = MatrixTrace(); return FUNCTION; } +transpose { *yylval = MatrixTranspose(); return FUNCTION; } +undef { *yylval = Undefined(); return UNDEFINED; } +inf { *yylval = Undefined(); return UNDEFINED; } +\x8a { *yylval = Poincare::Symbol(yytext[0]); return SYMBOL; } +\x8c { *yylval = Poincare::Symbol(yytext[0]); return SYMBOL; } +\x8f { *yylval = Poincare::Symbol(yytext[0]); return SYMBOL; } \x90 { return STO; } -\x91 { yylval->expression = SquareRoot(); return FUNCTION; } +\x91 { *yylval = SquareRoot(); return FUNCTION; } = { return EQUAL; } \+ { return PLUS; } \- { return MINUS; } @@ -173,7 +173,7 @@ inf { yylval->expression = Undefined(); return UNDEFINED; } \] { return RIGHT_BRACKET; } \, { return COMMA; } \_ { return UNDERSCORE; } -\x97 { yylval->expression = EmptyExpression(); return EMPTY; } +\x97 { *yylval = EmptyExpression(); return EMPTY; } [ ]+ /* Ignore whitespaces */ . { return UNDEFINED_SYMBOL; } diff --git a/poincare/src/expression_lexer_parser.h b/poincare/src/expression_lexer_parser.h index b00c00563..024942b87 100644 --- a/poincare/src/expression_lexer_parser.h +++ b/poincare/src/expression_lexer_parser.h @@ -1,12 +1,7 @@ #include /* Usually, YYSTYPE is defined as the union of the objects it might be. Here, - * some of these objects are non-trivial (specific copy-constructors and - * destructors), so they cannot be part of a union. We must use a struct to - * define YYSTYPE. */ + * Expression is non-trivial (specific copy-constructors and destructors), so + * it cannot be part of a union. */ -struct OurNodeValue{ - Poincare::Expression expression; -}; - -#define YYSTYPE OurNodeValue +#define YYSTYPE Poincare::Expression diff --git a/poincare/src/expression_parser.y b/poincare/src/expression_parser.y index 790b1caf7..d1f7da4a0 100644 --- a/poincare/src/expression_parser.y +++ b/poincare/src/expression_parser.y @@ -38,65 +38,11 @@ void poincare_expression_yyerror(Poincare::Expression * expressionOutput, char c #define YYCOPY(To, From, Count) memcpy(To, From, (Count)*sizeof(*(From))) using namespace Poincare; -#if 0 -//TODO move comments - -/* All symbols (both terminals and non-terminals) may have a value associated - * with them. In our case, it's going to be either an Expression (for example, - * when parsing (a/b) we want to create a new Division), or a string (this will - * be useful to retrieve the value of Integers for example). */ -%union { - Poincare::Expression expression; - Poincare::Symbol symbol; -/* - Poincare::ListData * listData; - Poincare::MatrixData * matrixData; - Poincare::StaticHierarchy<0> * function; -*/ - - /* Caution: all the const char * are NOT guaranteed to be NULL-terminated! - * While Flex guarantees that yytext is NULL-terminated when building tokens, - * it does so by temporarily swapping in a NULL terminated in the input text. - * Of course that hack has vanished by the time the pointer is fed into Bison. - * We thus record the length of the char fed into Flex in a structure and give - * it to the object constructor called by Bison along with the char *. */ - struct { - char * address; - int length; - } string; - char character; -} -#endif %} - /* The INTEGER token uses the "string" part of the union to store its value */ -%token DIGITS -%token SYMBOL -%token FUNCTION -%token LOGFUNCTION -%token UNDEFINED -%token EMPTY -/* Operator tokens */ -%token PLUS -%token MINUS -%token MULTIPLY -%token DIVIDE -%token POW -%token BANG -%token LEFT_PARENTHESIS -%token RIGHT_PARENTHESIS -%token LEFT_BRACE -%token RIGHT_BRACE -%token LEFT_BRACKET -%token RIGHT_BRACKET -%token COMMA -%token UNDERSCORE -%token STO -%token EQUAL -%token UNDEFINED_SYMBOL /* Make the operators left associative. * This makes 1 - 2 - 5’ be ‘(1 - 2) - 5’ instead of ‘1 - (2 - 5)’. @@ -115,8 +61,7 @@ using namespace Poincare; /* Note that in bison, precedence of parsing depend on the order they are defined in here, the last * one has the highest precedence. */ -%nonassoc EQUAL -%nonassoc STO +%nonassoc EQUAL STO %left PLUS %left MINUS %left MULTIPLY @@ -138,36 +83,11 @@ using namespace Poincare; %nonassoc UNDEFINED %nonassoc SYMBOL %nonassoc EMPTY +%nonassoc UNDEFINED_SYMBOL -/* The "exp" symbol uses the "expression" part of the union. */ -%type final_exp; -%type term; -%type bang; -%type factor; -%type pow; -%type exp; -%type number; -%type symb; -%type lstData; -/* MATRICES_ARE_DEFINED */ -%type mtxData; - -/* FIXME: no destructors, Expressions are GCed */ -/* During error recovery, some symbols need to be discarded. We need to tell - * Bison how to get rid of them. Depending on the type of the symbol, it may - * have some heap-allocated data that need to be discarded. */ - -/* - -%destructor { delete $$; } FUNCTION -%destructor { delete $$; } UNDEFINED final_exp exp pow factor bang term number EMPTY -%destructor { delete $$; } lstData -*/ -/* MATRICES_ARE_DEFINED */ -/* -%destructor { delete $$; } mtxData -%destructor { delete $$; } symb -*/ +/* During error recovery, some symbols need to be discarded. No destructor need + * to be specified to Bison because all symbols are Poincare::Expression that + * are garbage collected. */ %% @@ -197,18 +117,6 @@ mtxData: LEFT_BRACKET lstData RIGHT_BRACKET { $$ = Matrix::EmptyMatrix(); static * an int32_t). */ number : DIGITS { $$ = $1; } -/* - | DOT DIGITS { $$ = Decimal(Decimal::mantissa(nullptr, 0, $2.address, $2.length, false), Decimal::exponent(nullptr, 0, $2.address, $2.length, nullptr, 0, false)); } - | DIGITS DOT DIGITS { $$ = Decimal(Decimal::mantissa($1.address, $1.length, $3.address, $3.length, false), Decimal::exponent($1.address, $1.length, $3.address, $3.length, nullptr, 0, false)); } - | DOT DIGITS EE DIGITS { if ($4.length > 4) { YYERROR; }; int exponent = Decimal::exponent(nullptr, 0, $2.address, $2.length, $4.address, $4.length, false); if (exponent > 1000 || exponent < -1000 ) { YYERROR; }; $$ = Decimal(Decimal::mantissa(nullptr, 0, $2.address, $2.length, false), exponent); } - | DIGITS DOT DIGITS EE DIGITS { if ($5.length > 4) { YYERROR; }; int exponent = Decimal::exponent($1.address, $1.length, $3.address, $3.length, $5.address, $5.length, false); if (exponent > 1000 || exponent < -1000 ) { YYERROR; }; $$ = Decimal(Decimal::mantissa($1.address, $1.length, $3.address, $3.length, false), exponent); } - | DIGITS EE DIGITS { if ($3.length > 4) { YYERROR; }; int exponent = Decimal::exponent($1.address, $1.length, nullptr, 0, $3.address, $3.length, false); if (exponent > 1000 || exponent < -1000 ) { YYERROR; }; $$ = Decimal(Decimal::mantissa($1.address, $1.length, nullptr, 0, false), exponent); } - | DOT DIGITS EE MINUS DIGITS { if ($5.length > 4) { YYERROR; }; int exponent = Decimal::exponent(nullptr, 0, $2.address, $2.length, $5.address, $5.length, true); if (exponent > 1000 || exponent < -1000 ) { YYERROR; }; $$ = Decimal(Decimal::mantissa(nullptr, 0, $2.address, $2.length, false), exponent); } - | DIGITS DOT DIGITS EE MINUS DIGITS { if ($6.length > 4) { YYERROR; }; int exponent = Decimal::exponent($1.address, $1.length, $3.address, $3.length, $6.address, $6.length, true); if (exponent > 1000 || exponent < -1000 ) { YYERROR; }; $$ = new Decimal(Decimal::mantissa($1.address, $1.length, $3.address, $3.length, false), exponent); } - | DIGITS EE MINUS DIGITS { if ($4.length > 4) { YYERROR; }; int exponent = Decimal::exponent($1.address, $1.length, nullptr, 0, $4.address, $4.length, true); if (exponent > 1000 || exponent < -1000 ) { YYERROR; }; $$ = new Decimal(Decimal::mantissa($1.address, $1.length, nullptr, 0, false), exponent); } - ; -*/ - symb : SYMBOL { $$ = $1; } ; @@ -224,7 +132,6 @@ term : EMPTY { $$ = $1; } | FUNCTION LEFT_PARENTHESIS RIGHT_PARENTHESIS { if ($1.numberOfChildren() != 0) { YYERROR; } $$ = $1; } | LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = Parenthesis($2); } /* MATRICES_ARE_DEFINED */ - | LEFT_BRACKET mtxData RIGHT_BRACKET { $$ = $2; } ;