mirror of
				https://github.com/aportelli/LatAnalyze.git
				synced 2025-10-30 22:34:32 +00:00 
			
		
		
		
	math compiler support multi-expression code
This commit is contained in:
		| @@ -5,7 +5,7 @@ using namespace std; | |||||||
| using namespace Latan; | using namespace Latan; | ||||||
|  |  | ||||||
| // Math Bison/Flex parser declaration | // Math Bison/Flex parser declaration | ||||||
| int _math_parse(MathParserState* state); | int _math_parse(MathCompiler::MathParserState* state); | ||||||
|  |  | ||||||
| /****************************************************************************** | /****************************************************************************** | ||||||
|  *                        MathNode implementation                             * |  *                        MathNode implementation                             * | ||||||
| @@ -14,6 +14,7 @@ int _math_parse(MathParserState* state); | |||||||
| MathNode::MathNode(const string &name, const unsigned int type) | MathNode::MathNode(const string &name, const unsigned int type) | ||||||
| : name_(name) | : name_(name) | ||||||
| , type_(type) | , type_(type) | ||||||
|  | , parent_(NULL) | ||||||
| {} | {} | ||||||
|  |  | ||||||
| MathNode::MathNode(const std::string &name, const unsigned int type,\ | MathNode::MathNode(const std::string &name, const unsigned int type,\ | ||||||
| @@ -21,6 +22,7 @@ MathNode::MathNode(const std::string &name, const unsigned int type,\ | |||||||
| : name_(name) | : name_(name) | ||||||
| , type_(type) | , type_(type) | ||||||
| , arg_(nArg) | , arg_(nArg) | ||||||
|  | , parent_(NULL) | ||||||
| { | { | ||||||
|     va_list va; |     va_list va; | ||||||
|  |  | ||||||
| @@ -28,6 +30,7 @@ MathNode::MathNode(const std::string &name, const unsigned int type,\ | |||||||
|     for (unsigned int i = 0; i < nArg; ++i) |     for (unsigned int i = 0; i < nArg; ++i) | ||||||
|     { |     { | ||||||
|         arg_[i] = va_arg(va, MathNode*); |         arg_[i] = va_arg(va, MathNode*); | ||||||
|  |         arg_[i]->parent_ = this; | ||||||
|     } |     } | ||||||
|     va_end(va); |     va_end(va); | ||||||
| } | } | ||||||
| @@ -65,21 +68,10 @@ const MathNode &MathNode::operator[](const unsigned int i) const | |||||||
|     return *arg_[i]; |     return *arg_[i]; | ||||||
| } | } | ||||||
|  |  | ||||||
| /****************************************************************************** | // test //////////////////////////////////////////////////////////////////////// | ||||||
|  *                    MathParserState implementation                          * | bool MathNode::isRoot(void) const | ||||||
|  ******************************************************************************/ |  | ||||||
| // constructor ///////////////////////////////////////////////////////////////// |  | ||||||
| MathParserState::MathParserState(std::istream *stream, std::string *name, |  | ||||||
|                                  MathNode **data) |  | ||||||
| : ParserState<MathNode *>(stream, name, data) |  | ||||||
| { | { | ||||||
|     initScanner(); |     return (parent_ == NULL); | ||||||
| } |  | ||||||
|  |  | ||||||
| // destructor ////////////////////////////////////////////////////////////////// |  | ||||||
| MathParserState::~MathParserState(void) |  | ||||||
| { |  | ||||||
|     destroyScanner(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /****************************************************************************** | /****************************************************************************** | ||||||
| @@ -146,9 +138,13 @@ Pop::Pop(const string &name) | |||||||
| : name_(name) | : name_(name) | ||||||
| {} | {} | ||||||
|  |  | ||||||
|  |  | ||||||
| void Pop::operator()(std::stack<double> &dStack, VarTable &vTable) | void Pop::operator()(std::stack<double> &dStack, VarTable &vTable) | ||||||
|  | { | ||||||
|  |     if (!name_.empty()) | ||||||
|     { |     { | ||||||
|         vTable[name_] = dStack.top(); |         vTable[name_] = dStack.top(); | ||||||
|  |     } | ||||||
|     dStack.pop(); |     dStack.pop(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -157,6 +153,24 @@ void Pop::print(std::ostream &out) const | |||||||
|     out << CODE_MOD << "pop" << CODE_MOD << name_; |     out << CODE_MOD << "pop" << CODE_MOD << name_; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | Store::Store(const string &name) | ||||||
|  | : name_(name) | ||||||
|  | {} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void Store::operator()(std::stack<double> &dStack, VarTable &vTable) | ||||||
|  | { | ||||||
|  |     if (!name_.empty()) | ||||||
|  |     { | ||||||
|  |         vTable[name_] = dStack.top(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Store::print(std::ostream &out) const | ||||||
|  | { | ||||||
|  |     out << CODE_MOD << "store" << CODE_MOD << name_; | ||||||
|  | } | ||||||
|  |  | ||||||
| #define DEF_OP(name, nArg, exp, insName)\ | #define DEF_OP(name, nArg, exp, insName)\ | ||||||
| void name::operator()(stack<double> &dStack, VarTable &vTable __dumb)\ | void name::operator()(stack<double> &dStack, VarTable &vTable __dumb)\ | ||||||
| {\ | {\ | ||||||
| @@ -197,12 +211,25 @@ ostream &Latan::operator<<(ostream &out, const VirtualProgram &prog) | |||||||
| /****************************************************************************** | /****************************************************************************** | ||||||
|  *                       MathCompiler implementation                          * |  *                       MathCompiler implementation                          * | ||||||
|  ******************************************************************************/ |  ******************************************************************************/ | ||||||
|  | // MathParserState constructor ///////////////////////////////////////////////// | ||||||
|  | MathCompiler::MathParserState::MathParserState(istream *stream, string *name, | ||||||
|  |                                                vector<MathNode *> *data) | ||||||
|  | : ParserState<vector<MathNode *> >(stream, name, data) | ||||||
|  | { | ||||||
|  |     initScanner(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // MathParserState destructor ////////////////////////////////////////////////// | ||||||
|  | MathCompiler::MathParserState::~MathParserState(void) | ||||||
|  | { | ||||||
|  |     destroyScanner(); | ||||||
|  | } | ||||||
|  |  | ||||||
| // constructors //////////////////////////////////////////////////////////////// | // constructors //////////////////////////////////////////////////////////////// | ||||||
| MathCompiler::MathCompiler(void) | MathCompiler::MathCompiler(void) | ||||||
| : code_(NULL) | : code_(NULL) | ||||||
| , codeName_("<no_code>") | , codeName_("<no_code>") | ||||||
| , state_(NULL) | , state_(NULL) | ||||||
| , root_(NULL) |  | ||||||
| , out_() | , out_() | ||||||
| , status_(Status::none) | , status_(Status::none) | ||||||
| {} | {} | ||||||
| @@ -227,8 +254,8 @@ void MathCompiler::init(const std::string &code) | |||||||
|     } |     } | ||||||
|     code_     = new stringstream(code); |     code_     = new stringstream(code); | ||||||
|     codeName_ = "<string>"; |     codeName_ = "<string>"; | ||||||
|     state_    = new MathParserState(code_, &codeName_, &root_); |     state_    = new MathParserState(code_, &codeName_, &expr_); | ||||||
|     status_  |= Status::initialised; |     status_   = Status::initialised; | ||||||
| } | } | ||||||
|  |  | ||||||
| const VirtualProgram& MathCompiler::operator()(void) | const VirtualProgram& MathCompiler::operator()(void) | ||||||
| @@ -236,10 +263,13 @@ const VirtualProgram& MathCompiler::operator()(void) | |||||||
|     if (!(status_ & Status::parsed)) |     if (!(status_ & Status::parsed)) | ||||||
|     { |     { | ||||||
|         parse(); |         parse(); | ||||||
|  |         status_ |= Status::parsed; | ||||||
|  |         status_ -= status_ & Status::compiled; | ||||||
|     } |     } | ||||||
|     if (!(status_ & Status::compiled)) |     if (!(status_ & Status::compiled)) | ||||||
|     { |     { | ||||||
|         compile(*root_); |         compile(expr_); | ||||||
|  |         status_ |= Status::compiled; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     return out_; |     return out_; | ||||||
| @@ -249,54 +279,97 @@ const VirtualProgram& MathCompiler::operator()(void) | |||||||
| void MathCompiler::parse(void) | void MathCompiler::parse(void) | ||||||
| { | { | ||||||
|     _math_parse(state_); |     _math_parse(state_); | ||||||
|     status_ |= Status::parsed; |  | ||||||
|     status_ -= status_ & Status::compiled; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| #define IFOP(name, nArg) if ((n.getName() == (name))&&(n.getNArg() == nArg)) | void MathCompiler::compile(const vector<MathNode *> &expr) | ||||||
| #define ELIFOP(name, nArg) else IFOP(name, nArg) | { | ||||||
|  |     string lastNode; | ||||||
|  |      | ||||||
|  |     for (unsigned int i = 0; i < expr.size(); ++i) | ||||||
|  |     { | ||||||
|  |         lastNode = expr[i]->getName(); | ||||||
|  |         if ((lastNode == "=")||(lastNode == "return")) | ||||||
|  |         { | ||||||
|  |             compile(*expr[i]); | ||||||
|  |             if (lastNode == "return") | ||||||
|  |             { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if (lastNode != "return") | ||||||
|  |     { | ||||||
|  |         LATAN_ERROR(Syntax, "expected 'return' in program '" + codeName_ + "'"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #define IFNODE(name, nArg) if ((n.getName() == (name))&&(n.getNArg() == nArg)) | ||||||
|  | #define ELIFNODE(name, nArg) else IFNODE(name, nArg) | ||||||
| #define ELSE else | #define ELSE else | ||||||
| void MathCompiler::compile(const MathNode& n) | void MathCompiler::compile(const MathNode& n) | ||||||
| { | { | ||||||
|     switch (n.getType()) |     switch (n.getType()) | ||||||
|     { |     { | ||||||
|         case MathNode::Type::Constant: |         case MathNode::Type::cst: | ||||||
|             out_.push_back(new Push(strTo<double>(n.getName()))); |             out_.push_back(new Push(strTo<double>(n.getName()))); | ||||||
|             break; |             break; | ||||||
|         case MathNode::Type::Variable: |         case MathNode::Type::var: | ||||||
|             out_.push_back(new Push(n.getName())); |             out_.push_back(new Push(n.getName())); | ||||||
|             break; |             break; | ||||||
|         case MathNode::Type::Operator: |         case MathNode::Type::op: | ||||||
|  |             if (n.getName() == "=") | ||||||
|  |             { | ||||||
|  |                 compile(n[1]); | ||||||
|  |                 if (n.isRoot()) | ||||||
|  |                 { | ||||||
|  |                     out_.push_back(new Pop(n[0].getName())); | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     out_.push_back(new Store(n[0].getName())); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 for (unsigned int i = 0; i < n.getNArg(); ++i) | ||||||
|  |                 { | ||||||
|  |                     compile(n[i]); | ||||||
|  |                 } | ||||||
|  |                   IFNODE("-", 1) out_.push_back(new Neg); | ||||||
|  |                 ELIFNODE("+", 2) out_.push_back(new Add); | ||||||
|  |                 ELIFNODE("-", 2) out_.push_back(new Sub); | ||||||
|  |                 ELIFNODE("*", 2) out_.push_back(new Mul); | ||||||
|  |                 ELIFNODE("/", 2) out_.push_back(new Div); | ||||||
|  |                 ELIFNODE("^", 2) out_.push_back(new Pow); | ||||||
|  |                 ELSE LATAN_ERROR(Compilation, "unknown operator (node '" | ||||||
|  |                                  + n.getName() + "')"); | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |         case MathNode::Type::keyw:  | ||||||
|             for (unsigned int i = 0; i < n.getNArg(); ++i) |             for (unsigned int i = 0; i < n.getNArg(); ++i) | ||||||
|             { |             { | ||||||
|                 compile(n[i]); |                 compile(n[i]); | ||||||
|             } |             } | ||||||
|             IFOP("-",1)   out_.push_back(new Neg); |  | ||||||
|             ELIFOP("+",2) out_.push_back(new Add); |  | ||||||
|             ELIFOP("-",2) out_.push_back(new Sub); |  | ||||||
|             ELIFOP("*",2) out_.push_back(new Mul); |  | ||||||
|             ELIFOP("/",2) out_.push_back(new Div); |  | ||||||
|             ELIFOP("^",2) out_.push_back(new Pow); |  | ||||||
|             ELSE LATAN_ERROR(Compilation, |  | ||||||
|                              "unknown operator (node '" + n.getName() + "')"); |  | ||||||
|             break; |             break; | ||||||
|         default: |         default: | ||||||
|             LATAN_ERROR(Compilation, |             LATAN_ERROR(Compilation, | ||||||
|                         "unknown node type (node '" + n.getName() + "')"); |                         "unknown node type (node '" + n.getName() + "')"); | ||||||
|             break; |             break; | ||||||
|     } |     } | ||||||
|     status_ |= Status::compiled; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void MathCompiler::reset(void) | void MathCompiler::reset(void) | ||||||
| { | { | ||||||
|     VirtualProgram::iterator i; |  | ||||||
|      |  | ||||||
|     delete code_; |     delete code_; | ||||||
|     codeName_ = "<no_code>"; |     codeName_ = "<no_code>"; | ||||||
|     delete state_; |     delete state_; | ||||||
|     delete root_; |     for (vector<MathNode *>::iterator i = expr_.begin(); i != expr_.end(); ++i) | ||||||
|     for (i = out_.begin(); i != out_.end(); ++i) |     { | ||||||
|  |         delete *i; | ||||||
|  |     } | ||||||
|  |     expr_.clear(); | ||||||
|  |     for (VirtualProgram::iterator i = out_.begin(); i != out_.end(); ++i) | ||||||
|     { |     { | ||||||
|         delete *i; |         delete *i; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -24,9 +24,10 @@ public: | |||||||
|     public: |     public: | ||||||
|         enum |         enum | ||||||
|         { |         { | ||||||
|             Constant = 0, |             cst  = 0, | ||||||
|             Operator = 1, |             op   = 1, | ||||||
|             Variable = 2 |             var  = 2, | ||||||
|  |             keyw = 3 | ||||||
|         }; |         }; | ||||||
|     }; |     }; | ||||||
| public: | public: | ||||||
| @@ -40,27 +41,15 @@ public: | |||||||
|     const std::string& getName(void) const; |     const std::string& getName(void) const; | ||||||
|     unsigned int       getType(void) const; |     unsigned int       getType(void) const; | ||||||
|     unsigned int       getNArg(void) const; |     unsigned int       getNArg(void) const; | ||||||
|     // operators |     // operator | ||||||
|     const MathNode &operator[](const unsigned int i) const; |     const MathNode &operator[](const unsigned int i) const; | ||||||
|  |     // test | ||||||
|  |     bool isRoot(void) const; | ||||||
| private: | private: | ||||||
|     // private members |  | ||||||
|     std::string             name_; |     std::string             name_; | ||||||
|     unsigned int            type_; |     unsigned int            type_; | ||||||
|     std::vector<MathNode *> arg_; |     std::vector<MathNode *> arg_; | ||||||
| }; |     const MathNode *        parent_; | ||||||
|  |  | ||||||
| class MathParserState: public ParserState<MathNode *> |  | ||||||
| { |  | ||||||
| public: |  | ||||||
|     // constructor |  | ||||||
|     explicit MathParserState(std::istream *stream, std::string *name, |  | ||||||
|                              MathNode **data); |  | ||||||
|     // destructor |  | ||||||
|     virtual ~MathParserState(void); |  | ||||||
| private: |  | ||||||
|     // allocation/deallocation functions defined in MathLexer.lpp |  | ||||||
|     virtual void initScanner(void); |  | ||||||
|     virtual void destroyScanner(void); |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /****************************************************************************** | /****************************************************************************** | ||||||
| @@ -80,7 +69,7 @@ private: | |||||||
|     virtual void print(std::ostream &out) const = 0; |     virtual void print(std::ostream &out) const = 0; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| // push and pop | // push, pop and store | ||||||
| class Push: public Instruction | class Push: public Instruction | ||||||
| { | { | ||||||
| private: | private: | ||||||
| @@ -120,6 +109,19 @@ private: | |||||||
|     std::string name_; |     std::string name_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | class Store: public Instruction | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     //constructor | ||||||
|  |     explicit Store(const std::string &name); | ||||||
|  |     // instruction execution | ||||||
|  |     virtual void operator()(std::stack<double> &dStack, VarTable &vTable); | ||||||
|  | private: | ||||||
|  |     virtual void print(std::ostream& out) const; | ||||||
|  | private: | ||||||
|  |     std::string name_; | ||||||
|  | }; | ||||||
|  |  | ||||||
| // Float operations | // Float operations | ||||||
| #define DECL_OP(name)\ | #define DECL_OP(name)\ | ||||||
| class name: public Instruction\ | class name: public Instruction\ | ||||||
| @@ -150,7 +152,23 @@ public: | |||||||
|  ******************************************************************************/ |  ******************************************************************************/ | ||||||
| class MathCompiler | class MathCompiler | ||||||
| { | { | ||||||
|  | public: | ||||||
|  |     // parser state | ||||||
|  |     class MathParserState: public ParserState<std::vector<MathNode *> > | ||||||
|  |     { | ||||||
|  |     public: | ||||||
|  |         // constructor | ||||||
|  |         explicit MathParserState(std::istream *stream, std::string *name, | ||||||
|  |                                  std::vector<MathNode *> *data); | ||||||
|  |         // destructor | ||||||
|  |         virtual ~MathParserState(void); | ||||||
|     private: |     private: | ||||||
|  |         // allocation/deallocation functions defined in MathLexer.lpp | ||||||
|  |         virtual void initScanner(void); | ||||||
|  |         virtual void destroyScanner(void); | ||||||
|  |     }; | ||||||
|  | private: | ||||||
|  |     // status flags | ||||||
|     class Status |     class Status | ||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
| @@ -173,13 +191,14 @@ public: | |||||||
|     const VirtualProgram &operator()(void); |     const VirtualProgram &operator()(void); | ||||||
| private: | private: | ||||||
|     void parse(void); |     void parse(void); | ||||||
|  |     void compile(const std::vector<MathNode *> &expr); | ||||||
|     void compile(const MathNode &node); |     void compile(const MathNode &node); | ||||||
|     void reset(void); |     void reset(void); | ||||||
| private: | private: | ||||||
|     std::istream            *code_; |     std::istream            *code_; | ||||||
|     std::string             codeName_; |     std::string             codeName_; | ||||||
|     MathParserState         *state_; |     MathParserState         *state_; | ||||||
|     MathNode         *root_; |     std::vector<MathNode *> expr_; | ||||||
|     VirtualProgram          out_; |     VirtualProgram          out_; | ||||||
|     unsigned int            status_; |     unsigned int            status_; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ | |||||||
|     using namespace std; |     using namespace std; | ||||||
|     using namespace Latan; |     using namespace Latan; | ||||||
|      |      | ||||||
| 	#define YY_EXTRA_TYPE  MathParserState* | 	#define YY_EXTRA_TYPE  MathCompiler::MathParserState * | ||||||
| 	#define YY_USER_ACTION \ | 	#define YY_USER_ACTION \ | ||||||
|     yylloc->first_line   = yylloc->last_line = yylineno;\ |     yylloc->first_line   = yylloc->last_line = yylineno;\ | ||||||
|     yylloc->first_column = yylloc->last_column + 1;\ |     yylloc->first_column = yylloc->last_column + 1;\ | ||||||
| @@ -41,7 +41,9 @@ | |||||||
| DIGIT   [0-9] | DIGIT   [0-9] | ||||||
| ALPHA   [a-zA-Z_] | ALPHA   [a-zA-Z_] | ||||||
| FLOAT   (({DIGIT}+(\.{DIGIT}*)?)|({DIGIT}*\.{DIGIT}+))([eE][+-]?{DIGIT}+)? | FLOAT   (({DIGIT}+(\.{DIGIT}*)?)|({DIGIT}*\.{DIGIT}+))([eE][+-]?{DIGIT}+)? | ||||||
| OP      [+\-*/^] | KEYWORD return | ||||||
|  | END     ; | ||||||
|  | OP      [+\-*/^=] | ||||||
| PAR     [()] | PAR     [()] | ||||||
| BLANK   [ \t] | BLANK   [ \t] | ||||||
|  |  | ||||||
| @@ -52,24 +54,26 @@ BLANK   [ \t] | |||||||
|                                RETTOK(FLOAT); |                                RETTOK(FLOAT); | ||||||
|                           } |                           } | ||||||
| {OP}                      {RET(*yytext);} | {OP}                      {RET(*yytext);} | ||||||
|  | {KEYWORD}                 {RET(*yytext);} | ||||||
| {PAR}                     {RET(*yytext);} | {PAR}                     {RET(*yytext);} | ||||||
| {ALPHA}({ALPHA}|{DIGIT})* { | {ALPHA}({ALPHA}|{DIGIT})* { | ||||||
|                                strncpy(yylval->val_str,yytext,MAXIDLENGTH); |                                strncpy(yylval->val_str,yytext,MAXIDLENGTH); | ||||||
|                                RETTOK(ID); |                                RETTOK(ID); | ||||||
|                           } |                           } | ||||||
|  | {END}                     {RETTOK(END);} | ||||||
| <*>\n                     {yylloc->last_column = 0;} | <*>\n                     {yylloc->last_column = 0;} | ||||||
| <*>{BLANK} | <*>{BLANK} | ||||||
| <*>.                      {yylval->val_char = yytext[0]; RETTOK(ERR);} | <*>.                      {yylval->val_char = yytext[0]; RETTOK(ERR);} | ||||||
|  |  | ||||||
| %% | %% | ||||||
|  |  | ||||||
| void MathParserState::initScanner() | void MathCompiler::MathParserState::initScanner() | ||||||
| { | { | ||||||
| 	yylex_init(&scanner); | 	yylex_init(&scanner); | ||||||
| 	yyset_extra(this, scanner); | 	yyset_extra(this, scanner); | ||||||
| } | } | ||||||
|  |  | ||||||
| void MathParserState::destroyScanner() | void MathCompiler::MathParserState::destroyScanner() | ||||||
| { | { | ||||||
| 	yylex_destroy(scanner); | 	yylex_destroy(scanner); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ | |||||||
| %locations | %locations | ||||||
| %defines | %defines | ||||||
| %error-verbose | %error-verbose | ||||||
| %parse-param { Latan::MathParserState* state } | %parse-param { Latan::MathCompiler::MathParserState *state } | ||||||
| %initial-action {yylloc.last_column = 0;} | %initial-action {yylloc.last_column = 0;} | ||||||
| %lex-param { void* scanner } | %lex-param { void* scanner } | ||||||
|  |  | ||||||
| @@ -23,28 +23,32 @@ | |||||||
| 	double           val_double; | 	double           val_double; | ||||||
|     char             val_char; |     char             val_char; | ||||||
|     char             val_str[MAXIDLENGTH]; |     char             val_str[MAXIDLENGTH]; | ||||||
|     Latan::MathNode* val_nodept; |     Latan::MathNode *val_node; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | %token            END | ||||||
| %token <val_char> ERR | %token <val_char> ERR | ||||||
| %token <val_str>  FLOAT | %token <val_str>  FLOAT | ||||||
| %token <val_str>  ID | %token <val_str>  ID | ||||||
|  | %token <val_str>  KEYWORD | ||||||
|  |  | ||||||
|  | %left '=' | ||||||
| %left '+' '-' | %left '+' '-' | ||||||
| %left '*' '/' | %left '*' '/' | ||||||
| %left '^' | %left '^' | ||||||
| %nonassoc UMINUS | %nonassoc UMINUS | ||||||
|  |  | ||||||
| %type <val_nodept> expr | %type <val_node> expr | ||||||
|  |  | ||||||
| %{ | %{ | ||||||
| 	int _math_lex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner); | 	int _math_lex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner); | ||||||
|  |  | ||||||
| 	void _math_error(YYLTYPE* locp, MathParserState* state, const char* err) | 	void _math_error(YYLTYPE *locp, MathCompiler::MathParserState *state, | ||||||
|  |                      const char *err) | ||||||
| 	{ | 	{ | ||||||
|         stringstream buf; |         stringstream buf; | ||||||
|          |          | ||||||
|         buf << *state->streamName << ":" << locp->first_line << ":"\ |         buf << *(state->streamName) << ":" << locp->first_line << ":"\ | ||||||
|             << locp->first_column << ": " << err; |             << locp->first_column << ": " << err; | ||||||
|         LATAN_ERROR(Parsing, buf.str()); |         LATAN_ERROR(Parsing, buf.str()); | ||||||
| 	} | 	} | ||||||
| @@ -56,25 +60,30 @@ | |||||||
|  |  | ||||||
| program: | program: | ||||||
|      /* empty string */ |      /* empty string */ | ||||||
|     | expr {*state->data = $1;} |     | program expr END {state->data->push_back($2);} | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
| expr: | expr: | ||||||
|       FLOAT |       FLOAT | ||||||
|     {$$ = new MathNode($FLOAT, MathNode::Type::Constant);} |     {$$ = new MathNode($FLOAT, MathNode::Type::cst);} | ||||||
|     | ID |     | ID | ||||||
|     {$$ = new MathNode($ID,MathNode::Type::Variable);} |     {$$ = new MathNode($ID,MathNode::Type::var);} | ||||||
|  |     | 'r' expr | ||||||
|  |     {$$ = new MathNode("return", MathNode::Type::keyw, 1, $2);} | ||||||
|     | '-' expr %prec UMINUS |     | '-' expr %prec UMINUS | ||||||
|     {$$ = new MathNode("-", MathNode::Type::Operator, 1,$2);} |     {$$ = new MathNode("-", MathNode::Type::op, 1, $2);} | ||||||
|  |     | expr '=' expr | ||||||
|  |     {$$ = new MathNode("=", MathNode::Type::op, 2, $1, $3);} | ||||||
|     | expr '+' expr |     | expr '+' expr | ||||||
|     {$$ = new MathNode("+", MathNode::Type::Operator, 2, $1, $3);} |     {$$ = new MathNode("+", MathNode::Type::op, 2, $1, $3);} | ||||||
|     | expr '-' expr |     | expr '-' expr | ||||||
|     {$$ = new MathNode("-", MathNode::Type::Operator, 2, $1, $3);} |     {$$ = new MathNode("-", MathNode::Type::op, 2, $1, $3);} | ||||||
|     | expr '*' expr |     | expr '*' expr | ||||||
|     {$$ = new MathNode("*", MathNode::Type::Operator, 2, $1, $3);} |     {$$ = new MathNode("*", MathNode::Type::op, 2, $1, $3);} | ||||||
|     | expr '/' expr |     | expr '/' expr | ||||||
|     {$$ = new MathNode("/", MathNode::Type::Operator, 2, $1, $3);} |     {$$ = new MathNode("/", MathNode::Type::op, 2, $1, $3);} | ||||||
|     | expr '^' expr |     | expr '^' expr | ||||||
|     {$$ = new MathNode("^", MathNode::Type::Operator, 2, $1, $3);} |     {$$ = new MathNode("^", MathNode::Type::op, 2, $1, $3);} | ||||||
|     | '(' expr ')' {$$ = $2;} |     | '(' expr ')' | ||||||
|  |     {$$ = $2;} | ||||||
|     ; |     ; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user