mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-19 05:40:38 +01:00
96 lines
3.1 KiB
Plaintext
96 lines
3.1 KiB
Plaintext
/* This file has been tested with Bison 2.3. It should work with newer versions
|
||
* but it hasn't been tested. */
|
||
%{
|
||
/* We will be generating all kind of Expressions, so we need their definitions
|
||
* here. */
|
||
#include <poincare.h>
|
||
|
||
/* expression_lexer.hpp expects YYSTYPE to be defined. It is defined in the
|
||
* expression_parser.hpp file, which must be included before. */
|
||
#include "expression_parser.hpp"
|
||
#include "expression_lexer.hpp"
|
||
|
||
|
||
/* Declare our error-handling function. Since we're making a re-entrant parser,
|
||
* it takes a "context" parameter as its first input. */
|
||
void poincare_expression_yyerror(yyscan_t scanner, Expression ** expressionOutput, char const *msg);
|
||
|
||
/* Bison expects to use __builtin_memcpy. We don't want to provide this, but
|
||
* instead we do provide regular memcpy. Let's instruct Bison to use it. */
|
||
#define YYCOPY(To, From, Count) memcpy(To, From, (Count)*sizeof(*(From)))
|
||
|
||
%}
|
||
|
||
/* We want a reentrant parser. Otherwise Bison makes use of global variables,
|
||
* which we want to avoid. */
|
||
%pure-parser
|
||
|
||
/* Our lexer and parser are reentrant. That means that their generated functions
|
||
* (such as *yylex) take a "context" as an input parameter. We're telling Bison
|
||
* That this input will be a "yyscan_t" named "scanner". */
|
||
%lex-param { yyscan_t scanner }
|
||
%parse-param { yyscan_t scanner }
|
||
|
||
/* When calling the parser, we will provide yyparse with a backpointer to the
|
||
* resulting expression. */
|
||
%parse-param { Expression ** expressionOutput }
|
||
|
||
|
||
/* 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 Fraction), or a string (this will
|
||
* be useful to retrieve the value of Integers for example). */
|
||
%union {
|
||
Expression * expression;
|
||
char * string;
|
||
}
|
||
|
||
/* The INTEGER token uses the "string" part of the union to store its value */
|
||
%token <string> INTEGER
|
||
%token <string> SYMBOL
|
||
|
||
/* Operator tokens */
|
||
%token PLUS
|
||
%token MINUS
|
||
%token MULTIPLY
|
||
%token DIVIDE
|
||
%token POW
|
||
%token LEFT_PARENTHESIS
|
||
%token RIGHT_PARENTHESIS
|
||
|
||
/* Make the operators left associative.
|
||
* This makes 1 - 2 - 5’ be ‘(1 - 2) - 5’ instead of ‘1 - (2 - 5)’.
|
||
* This makes 1 / 2 / 5’ be ‘(1 / 2) / 5’ instead of ‘1 / (2 / 5)’.
|
||
*/
|
||
%left '-' '+'
|
||
%left '*' '/'
|
||
|
||
/* The "exp" symbol uses the "expression" part of the union. */
|
||
%type <expression> exp;
|
||
|
||
%%
|
||
|
||
Root:
|
||
exp {
|
||
*expressionOutput = $1;
|
||
}
|
||
|
||
/* Note that in bison, precedence of parsing depend on the order they are defined in here, the last
|
||
* one has the highest precedence. */
|
||
exp:
|
||
INTEGER { $$ = new Integer($1); }
|
||
| SYMBOL { $$ = new Symbol($1); }
|
||
| exp PLUS exp { $$ = new Addition($1,$3); }
|
||
| exp MINUS exp { $$ = new Substraction($1,$3); }
|
||
| exp MULTIPLY exp { $$ = new Product($1,$3); }
|
||
| exp DIVIDE exp { $$ = new Fraction($1,$3); }
|
||
| exp POW exp { $$ = new Power($1,$3); }
|
||
| LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = $2; }
|
||
;
|
||
|
||
%%
|
||
|
||
void poincare_expression_yyerror(yyscan_t scanner, Expression ** expressionOutput, char const *msg) {
|
||
// Handle the error!
|
||
}
|