Parsing of string to Expression

This commit is contained in:
Romain Goyet
2015-05-20 17:34:18 +02:00
parent 2e5e851caa
commit c851a06b74
6 changed files with 75 additions and 12 deletions

View File

@@ -5,6 +5,8 @@ extern "C" {
#include <kandinsky.h>
}
void CreateFromString(char * string);
class Expression;
typedef void (Expression::*ExpressionAction)(void);

View File

@@ -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];
};

View File

@@ -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);
}

View File

@@ -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); }
%%

View File

@@ -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!
}

View File

@@ -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;
}