mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
Parsing of string to Expression
This commit is contained in:
@@ -5,6 +5,8 @@ extern "C" {
|
||||
#include <kandinsky.h>
|
||||
}
|
||||
|
||||
void CreateFromString(char * string);
|
||||
|
||||
class Expression;
|
||||
typedef void (Expression::*ExpressionAction)(void);
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
class Number : public Expression {
|
||||
public:
|
||||
Number(int v);
|
||||
Number(char * string);
|
||||
//Number(int v);
|
||||
virtual void draw();
|
||||
virtual Expression ** children();
|
||||
protected:
|
||||
virtual void layout();
|
||||
private:
|
||||
int m_value;
|
||||
char m_stringValue[16];
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "expression_parser.hpp"
|
||||
#include "expression_lexer.hpp"
|
||||
|
||||
int poincare_expression_yyparse(yyscan_t scanner);
|
||||
int poincare_expression_yyparse(yyscan_t scanner, Expression ** expressionOutput);
|
||||
|
||||
void CreateFromString(char * string) {
|
||||
yyscan_t scanner;
|
||||
@@ -11,8 +11,14 @@ void CreateFromString(char * string) {
|
||||
poincare_expression_yylex_init(&scanner);
|
||||
buf = poincare_expression_yy_scan_string(string, scanner);
|
||||
void * selector = 0;
|
||||
//CSSSelector * selector = nullptr;
|
||||
poincare_expression_yyparse(scanner);//, &selector);
|
||||
Expression * expression = 0;
|
||||
poincare_expression_yyparse(scanner, &expression);
|
||||
|
||||
|
||||
expression->recursiveLayout();
|
||||
expression->m_frame.origin = KDPOINT(0, 0);
|
||||
expression->recursiveDraw();
|
||||
|
||||
poincare_expression_yy_delete_buffer(buf, scanner);
|
||||
poincare_expression_yylex_destroy(scanner);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
%{
|
||||
|
||||
/* Flex's job is to generate tokens that will be fed to the parser. Each token
|
||||
* can be attached a value. The type of this value is specified in the Bison
|
||||
* file. In our case, it can be a Poincare Expression. Therefore we need the
|
||||
* definition of these types, hence the include.
|
||||
* Note that those have to come before including the parser header, because the
|
||||
* parser also needs those types to be defined. */
|
||||
#include <poincare.h>
|
||||
|
||||
/* Flex generate a lexer, which outputs tokens. Strangely enough, tokens end up
|
||||
* being defined by Bison in the parser's header file. Since we'll emit tokens
|
||||
* in our C file, we'll definitely need their definition, hence this include. */
|
||||
#include "expression_parser.hpp"
|
||||
|
||||
|
||||
/* Flex has provision for reading files. We'll never use this, so we're defining
|
||||
* YY_INPUT which effectively disable taking input from a file. */
|
||||
#define YY_INPUT
|
||||
@@ -38,7 +48,8 @@
|
||||
|
||||
%%
|
||||
|
||||
[0-9]+ { return(INTEGER); }
|
||||
[0-9]+ { yylval->string = yytext; return(INTEGER); }
|
||||
\/ { return(DIVIDE); }
|
||||
|
||||
%%
|
||||
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
/* 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, char const *msg);
|
||||
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. */
|
||||
@@ -33,6 +38,30 @@ void poincare_expression_yyerror(yyscan_t scanner, char const *msg);
|
||||
* 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
|
||||
|
||||
/* The DIVIDE token uses no value */
|
||||
%token DIVIDE
|
||||
|
||||
/* The "exp" symbol uses the "expression" part of the union. */
|
||||
%type <expression> exp;
|
||||
|
||||
/*
|
||||
//Expression * expression;
|
||||
//CSSSelector * selector;
|
||||
@@ -51,15 +80,18 @@ void poincare_expression_yyerror(yyscan_t scanner, char const *msg);
|
||||
%type <selector> Expression;
|
||||
*/
|
||||
|
||||
%token INTEGER
|
||||
|
||||
%%
|
||||
|
||||
Root:
|
||||
INTEGER {
|
||||
$$ = 3;
|
||||
exp {
|
||||
*expressionOutput = $1;
|
||||
}
|
||||
|
||||
exp: INTEGER { $$ = new Number($1); }
|
||||
| exp DIVIDE exp { $$ = new Fraction($1,$3); }
|
||||
;
|
||||
|
||||
/*
|
||||
|
||||
Root:
|
||||
@@ -99,7 +131,7 @@ Selector:
|
||||
*/
|
||||
%%
|
||||
|
||||
void poincare_expression_yyerror(yyscan_t scanner, char const *msg) {
|
||||
void poincare_expression_yyerror(yyscan_t scanner, Expression ** expressionOutput, char const *msg) {
|
||||
// Handle the error!
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <kandinsky/text.h>
|
||||
#include <string.h>
|
||||
|
||||
Number::Number(int v) : m_value(v) {
|
||||
/*Number::Number(int v) : m_value(v) {
|
||||
for (int i=0; i<16; i++) {
|
||||
m_stringValue[i] = 0;
|
||||
}
|
||||
@@ -16,8 +16,20 @@ Number::Number(int v) : m_value(v) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
Number::Number(char * string) {
|
||||
// FIXME: use strdup
|
||||
memset(m_stringValue, 0, 16);
|
||||
for (int i=0;i<15;i++) {
|
||||
if (string[i] == 0) {
|
||||
break;
|
||||
}
|
||||
m_stringValue[i] = string[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Expression ** Number::children() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user