diff --git a/nodes/CStatementNode.cc b/nodes/CStatementNode.cc new file mode 100644 index 0000000..9ce67c3 --- /dev/null +++ b/nodes/CStatementNode.cc @@ -0,0 +1,12 @@ + +#include +#include +#include "Node.h" +#include "util/refptr.h" +using namespace std; + +void CStatementNode::process(FILE * out) +{ + fprintf(out, "%s", m_string.c_str()); + fprintf(out, "\n"); +} diff --git a/nodes/Node.cc b/nodes/Node.cc index c4f5e9e..9ea6bd3 100644 --- a/nodes/Node.cc +++ b/nodes/Node.cc @@ -1,6 +1,6 @@ -#include "Node.h" #include +#include "Node.h" #include "util/refptr.h" using namespace std; diff --git a/nodes/Node.h b/nodes/Node.h index 376cf0e..18c3022 100644 --- a/nodes/Node.h +++ b/nodes/Node.h @@ -2,6 +2,7 @@ #ifndef NODE_H #define NODE_H NODE_H +#include #include #include #include @@ -15,31 +16,52 @@ class Node void addChildren(refptr other); std::vector< refptr > & getChildren() { return m_children; } - virtual uint64_t getInteger() { return 0x0ULL; } - virtual std::string getString() { return ""; } + virtual double getDouble() { return m_double; } + virtual uint64_t getInteger() { return m_integer; } + virtual std::string getString() { return m_string; } virtual void process(FILE * out) { } protected: std::vector< refptr > m_children; + uint64_t m_integer; + std::string m_string; + double m_double; }; +class CStatementNode : public Node +{ + public: + CStatementNode(const std::string & str) { m_string = str; } + virtual void process(FILE * out); +}; + +class DoubleNode : public Node +{ + public: + DoubleNode(double val) { m_double = val; } +}; + +class IdentifierNode : public Node +{ + public: + IdentifierNode(const std::string & str) { m_string = str; } +}; + class IntegerNode : public Node { public: IntegerNode(uint64_t integer) { m_integer = integer; } - unsigned long getInteger() { return m_integer; } - protected: - uint64_t m_integer; +}; + +class ProgramNode : public Node +{ }; class StringNode : public Node { public: StringNode(const std::string & str) { m_string = str; } - std::string getString() { return m_string; } - protected: - std::string m_string; }; #endif diff --git a/parser/parser.lex b/parser/parser.lex index b5f68d6..d671b91 100644 --- a/parser/parser.lex +++ b/parser/parser.lex @@ -4,12 +4,31 @@ %{ +#include +#include #include "parser.h" #include "parser.tab.hh" -#include using namespace std; static string build_string; +static uint64_t parseInt(const char * text, int base) +{ + uint64_t val = 0; + for (const char * p = text; *p != '\0'; p++) + { + int digit = -1; + if (*p >= '0' && *p <= '9') digit = *p - '0'; + else if (*p >= 'A' && *p <= 'Z') digit = *p - 'A'; + else if (*p >= 'a' && *p <= 'z') digit = *p - 'a'; + if (digit != -1) + { + val *= base; + val += digit; + } + } + return val; +} + %} %x str @@ -47,17 +66,23 @@ static string build_string; \( return LPAREN; \) return RPAREN; - /* literals */ -[0-9]+ { + /* numeric literals */ +[0-9][0-9_]* { + *yylval = new IntegerNode(parseInt(yytext, 10)); return INT_LITERAL; } -0x[0-9A-Fa-f]+ { +0x[0-9A-Fa-f][0-9A-Fa-f_]* { + *yylval = new IntegerNode(parseInt(yytext + 2, 16)); return INT_LITERAL; } -0b[01]+ { +0b[01][01_]* { + *yylval = new IntegerNode(parseInt(yytext + 2, 2)); return INT_LITERAL; } [0-9]*\.[0-9]+([eE]-?[0-9]+)? { + double val; + (void) sscanf(yytext, "%lf", &val); + *yylval = new DoubleNode(val); return REAL_LITERAL; } @@ -84,6 +109,7 @@ struct return STRUCT; /* identifiers */ [a-zA-Z_][a-zA-Z_0-9]* { + *yylval = new IdentifierNode(yytext); return IDENTIFIER; } diff --git a/parser/parser.yy b/parser/parser.yy index 44d7512..b9cb775 100644 --- a/parser/parser.yy +++ b/parser/parser.yy @@ -91,7 +91,9 @@ static YYSTYPE parse_result; %% program: program_items { - } + $$ = new ProgramNode(); + $$->addChildren($1); + } ; program_items: /* empty */ @@ -187,7 +189,9 @@ type: primitive_type statement: expression SEMICOLON | return_statement - | c_statement + | c_statement { + $$ = $1; + } ; return_statement: RETURN expression SEMICOLON @@ -204,8 +208,8 @@ lvalue: IDENTIFIER ; c_statement: C LPAREN STRING_LITERAL RPAREN SEMICOLON { - printf("c_statement: '%s'\n", $3->getString().c_str()); - } + $$ = new CStatementNode($3->getString()); + } ; %%