From 8f6313b4cb034ccd5d3303eb08cdfdbbcd0fde14 Mon Sep 17 00:00:00 2001 From: hama Date: Mon, 21 Jul 2014 23:33:47 +0200 Subject: [PATCH] dayly work --- rplexpr/rplastree.cpp | 72 ++++++++++++++++++++++------------ rplexpr/rplastree.hpp | 16 ++++++-- rplexpr/rplmfparser.cpp | 16 ++++++-- test/rplmfparser/methc1.txt | 27 +++++++++++++ unittests/rplmfparser_test.cpp | 4 +- 5 files changed, 102 insertions(+), 33 deletions(-) create mode 100644 test/rplmfparser/methc1.txt diff --git a/rplexpr/rplastree.cpp b/rplexpr/rplastree.cpp index 5172b22..9f25c5b 100644 --- a/rplexpr/rplastree.cpp +++ b/rplexpr/rplastree.cpp @@ -1860,17 +1860,15 @@ void RplASTree::dump(const char* filename, int flags, const char* header) /** * @brief Constructor. */ -RplASMethodCall::RplASMethodCall() : +RplASMethodCall::RplASMethodCall(const QString& name) : RplASNode2(AST_METHOD_CALL), - RplASStatement() + RplASStatement(), + m_name(name), + m_method(NULL) { } -RplASMethodCall::~RplASMethodCall() -{ - -} /** * @brief Writes the internals into a file. @@ -1882,14 +1880,13 @@ void RplASMethodCall::dump(FILE* fp, int indent) { DEFINE_TABS(indent); char buffer[256]; - fprintf(fp, "%scall %d instance: %d args: %d %s\n", tabs, m_id, - m_child == NULL ? 0 : m_child->id(), + fprintf(fp, "%scall %s Id: %d args: %d succ: %d %s\n", tabs, + m_name.toUtf8().constData(), m_id, m_child2 == NULL ? 0 : m_child2->id(), + m_child == NULL ? 0 : m_child->id(), positionStr(buffer, sizeof buffer)); - if (m_child != NULL) - m_child->dump(fp, indent + 1); if (m_child2 != NULL) - m_child->dump(fp, indent + 1); + m_child2->dump(fp, indent + 1); } /** @@ -1930,15 +1927,6 @@ RplASArgument* RplASMethodCall::arg1() const * m_child: ???
* m_child2: argument list (or NULL) */ -/** - * @brief Sets the argument list. - * - * @param arg1 NULL or the first element of the argument list - */ -void RplASMethodCall::setArg1(RplASArgument* arg1) -{ - m_child2 = arg1; -} /** @class RplASBinaryOp rplastree.hpp "rplexpr/rplastree.hpp" * @@ -2057,10 +2045,10 @@ RplASArgument::RplASArgument() : */ void RplASArgument::dumpOne(FILE* fp, int no, int indent, char tabs[]) { - int succ = child() == NULL ? 0 : child()->id(); - fprintf(fp, "%sArg %d id: %d expr: %d succ: %d\n", tabs, no, m_id, + int succ = m_child == NULL ? 0 : m_child->id(); + fprintf(fp, "%sarg %d id: %d expr: %d succ: %d\n", tabs, no, m_id, child2()->id(), succ); - child2()->dump(fp, indent + 1); + m_child2->dump(fp, indent + 1); } /** @@ -2075,7 +2063,41 @@ void RplASArgument::dump(FILE* fp, int indent) RplASArgument* current = this; int no = 0; do { - dumpOne(fp, ++no, indent, tabs); + current->dumpOne(fp, ++no, indent, tabs); current = static_cast(current->child()); - } while (this != NULL); + } while (current != NULL); +} + +/** @class RplASField rplastree.hpp "rplexpr/rplastree.hpp" + * + * @brief Implements an argument of a method for the Abstract Syntax Tree. + * + * m_child: parent (variable, field, method)
+ */ + +/** + * @brief Constructor. + * + * @param name name of the field + */ +RplASField::RplASField(const QString& name) : + RplASNode1(AST_FIELD), + m_name(name) +{ +} + +/** + * @brief Writes the internals of the instance into a file. + * + * @param fp target file + * @param indent nesting level + */ +void RplASField::dump(FILE* fp, int indent) +{ + DEFINE_TABS(indent); + char buffer[256]; + fprintf(fp, "%sfield %s id: %d expr: %d succ: %s\n", tabs, + m_name.toUtf8().constData(), m_id, + m_child->id(), positionStr(buffer, sizeof buffer)); + m_child->dump(fp, indent + 1); } diff --git a/rplexpr/rplastree.hpp b/rplexpr/rplastree.hpp index d19339f..72c168f 100644 --- a/rplexpr/rplastree.hpp +++ b/rplexpr/rplastree.hpp @@ -18,6 +18,7 @@ enum RplASItemType { AST_MAP_CONSTANT, AST_MAP_ENTRY, AST_NAMED_VALUE, + AST_FIELD, AST_VAR_DEFINITION, AST_EXPR_STATEMENT, AST_METHOD, @@ -426,8 +427,7 @@ class RplASMethod; class RplASMethodCall : public RplASNode2, public RplASStatement { public: - RplASMethodCall(); - virtual ~RplASMethodCall(); + RplASMethodCall(const QString& name); public: void dump(FILE* fp, int indent); virtual void execute(); @@ -437,8 +437,8 @@ public: void setMethod(RplASMethod* method); RplASArgument*arg1() const; - void setArg1(RplASArgument* arg1); private: + QString m_name; RplASMethod* m_method; }; @@ -452,6 +452,16 @@ private: RplASNamedValue* m_default; }; +class RplASField : public RplASNode1 +{ +public: + RplASField(const QString& name); +public: + void dump(FILE* fp, int indent); +private: + QString m_name; +}; + class RplASClass; class RplASMethod : public RplASNode2 diff --git a/rplexpr/rplmfparser.cpp b/rplexpr/rplmfparser.cpp index 3124b72..91ad007 100644 --- a/rplexpr/rplmfparser.cpp +++ b/rplexpr/rplmfparser.cpp @@ -546,7 +546,7 @@ RplASItem* RplMFParser::parseOperand(int level) readNext = false; } else { if (token->id() == O_LPARENTH){ - RplASMethodCall* call = new RplASMethodCall(); + RplASMethodCall* call = new RplASMethodCall(name); call->setPosition(startPosition); rc = call; @@ -554,7 +554,8 @@ RplASItem* RplMFParser::parseOperand(int level) if (! token->isOperator(O_RPARENT)){ m_lexer.undoLastToken(); RplASArgument* args = parseArguments(); - call->setArg1(args); + call->setChild2(args); + readNext = false; } } else { RplASNamedValue* var = new RplASNamedValue(name); @@ -902,16 +903,25 @@ void RplMFParser::parse() RplASArgument* RplMFParser::parseArguments() { RplASArgument* first = NULL; + RplASArgument* last = NULL; bool again = false; do { RplASItem* expr = parseExpr(0); if (! m_lexer.currentToken()->isOperator(O_COMMA, O_RPARENT)) syntaxError(L_PARSE_ARGS_NO_COMMA_OR_PARENT, "',' or ')' expected"); again = m_lexer.currentToken()->isOperator(O_COMMA); - m_lexer.nextNonSpaceToken(); RplASArgument* current = new RplASArgument(); current->setPosition(expr->position()); + current->setChild2(expr); + if (first == NULL) + first = last = current; + else{ + last->setChild(current); + last = current; + } } while (again); + // skip ')': + m_lexer.nextNonSpaceToken(); return first; } diff --git a/test/rplmfparser/methc1.txt b/test/rplmfparser/methc1.txt new file mode 100644 index 0000000..0fe7a1f --- /dev/null +++ b/test/rplmfparser/methc1.txt @@ -0,0 +1,27 @@ +rand(); +sin(a); +max(1+2*3,4**(5-4)); += (module) parent: global +== Classes: +== Variables: +== Body: +Expr id: 2 expr: 1 succ: 6 :1:4 + call rand Id: 1 args: 0 succ: 0 :1:4 +Expr id: 6 expr: 3 succ: 20 :2:3 + call sin Id: 3 args: 5 succ: 0 :2:3 + Arg 1 id: 5 expr: 4 succ: 0 + namedValue a id: 4 attr: 0x0 :2:5 +Expr id: 20 expr: 7 succ: 0 :3:3 + call max Id: 7 args: 13 succ: 0 :3:3 + Arg 1 id: 13 expr: 9 succ: 19 + BinOp id: 9 op: + (26) left: 8 right: 11 :3:5 + const id: 8 value: 1 :3:4 + BinOp id: 11 op: * (30) left: 10 right: 12 :3:7 + const id: 10 value: 2 :3:6 + const id: 12 value: 3 :3:8 + Arg 2 id: 19 expr: 15 succ: 0 + BinOp id: 15 op: ** (31) left: 14 right: 17 :3:11 + const id: 14 value: 4 :3:10 + BinOp id: 17 op: - (27) left: 16 right: 18 :3:15 + const id: 16 value: 5 :3:14 + const id: 18 value: 4 :3:16 diff --git a/unittests/rplmfparser_test.cpp b/unittests/rplmfparser_test.cpp index 5a85d80..94d26f7 100644 --- a/unittests/rplmfparser_test.cpp +++ b/unittests/rplmfparser_test.cpp @@ -132,8 +132,8 @@ public: checkAST("map2.txt", __LINE__); } void methodCallTest(){ - setSource("max(4**(5),3.14*8));"); - //setSource("rand();\nsin(a);\nmax(1+2*3,4**(5-4));"); + //setSource("max(4,3.14);"); + setSource("rand();\nsin(a);\nmax(1+2*3,4**(5-4));"); RplMFParser parser(m_source, m_tree); parser.parse(); checkAST("methc1.txt", __LINE__); -- 2.39.5