From ea58b3887a7deba05e3fc85eb536038a547f8871 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 17 Jul 2016 18:56:29 +0200 Subject: lexer/parser: o Renaming the ASSERT_K token to ASSERT. o Fixing a bug in the NAME regex where underscored where not allowed in certain names. o All ASSERT statements use string instead of NAME. o Improving STRING_ANY, allow many non-quote tokens instead of just one. Can probably replace the entire string rule with STRING_ANY now. o Fixing naming of '!', "~" and "?" operators. Ld: o Implement support for multiplication and division operators. o Better error messages. --- Ld.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 16 deletions(-) (limited to 'Ld.cpp') diff --git a/Ld.cpp b/Ld.cpp index 8bacaea..16c40fa 100644 --- a/Ld.cpp +++ b/Ld.cpp @@ -7,10 +7,9 @@ namespace trygvis { namespace elfinfo { using antlr4::ANTLRFileStream; +using antlr4::tree::ParseTree; using namespace std; -using ParseTree = antlr4::tree::ParseTree; - static MemoryAttribute valueOf(char c) { switch (c) { case 'r': @@ -31,7 +30,7 @@ static bool endsWith(const string &a, const string &b) { return b.length() <= a.length() && a.compare(a.length() - b.length(), b.length(), b) == 0; } -template +template class ParseTreeProperty { public: virtual V get(Ref node) { @@ -39,21 +38,27 @@ public: } virtual V get(ParseTree *const node) { - return _annotations.at(node); - } + if (!debug) { + return _annotations.at(node); + } -// virtual V get(ParseTree *const node) { -// try { -// cout << "node = " << node->getText() << endl; -// return _annotations.at(node); -// } catch (std::out_of_range &e) { -// cout << "out of range: " << node->getText() << endl; -// throw e; -// } -// } + try { +// cout << "node = " << node->getText() << endl; + return _annotations.at(node); + } catch (std::out_of_range &e) { + cout << "get(" << node << "), text=" << node->getText() << endl; + stringstream buf; + buf << "out of range: " << node << ", text=" << node->getText(); + auto msg = buf.str(); + cout << msg << endl; + throw LdInternalErrorException(msg); + } + } virtual void put(ParseTree *const node, V value) { - // cout << "put(" << node << ", " << value << ")" << endl; + if (debug) { + cout << "put(" << node << ", " << value << "), text: " << node->getText() << endl; + } _annotations[node] = value; } @@ -131,6 +136,10 @@ public: expr.put(ctx, 0); } + virtual void exitExpDefined(GnuLdParser::ExpDefinedContext *ctx) override { + expr.put(ctx, 0); + } + void exitExpInt(GnuLdParser::ExpIntContext *ctx) override { uint64_t i = parseInt(ctx->INT()->getText()); expr.put(ctx, i); @@ -150,6 +159,20 @@ public: expr.put(ctx, x); } + void exitExpMul(GnuLdParser::ExpMulContext *ctx) override { + uint64_t a = expr.get(ctx->exp(0)); + uint64_t b = expr.get(ctx->exp(1)); + uint64_t x = a * b; + expr.put(ctx, x); + } + + void exitExpDiv(GnuLdParser::ExpDivContext *ctx) override { + uint64_t a = expr.get(ctx->exp(0)); + uint64_t b = expr.get(ctx->exp(1)); + uint64_t x = b > 0 ? a / b : 0; + expr.put(ctx, x); + } + void exitExpName(GnuLdParser::ExpNameContext *ctx) override { expr.put(ctx, 0); } @@ -176,11 +199,23 @@ public: expr.put(ctx, expr.get(ctx->exp())); } + void exitExpParen(GnuLdParser::ExpParenContext *ctx) override { + expr.put(ctx, expr.get(ctx->exp())); + } + void exitExpLoadaddr(GnuLdParser::ExpLoadaddrContext *ctx) override { auto §ion = getSection(ctx->NAME()->getText()); expr.put(ctx, 0); } + void exitExpTernary(GnuLdParser::ExpTernaryContext *ctx) override { + uint64_t a = expr.get(ctx->exp(0)); + uint64_t b = expr.get(ctx->exp(1)); + uint64_t c = expr.get(ctx->exp(2)); + uint64_t x = a ? b : c; + expr.put(ctx, x); + } + void exitExpConstant(GnuLdParser::ExpConstantContext *ctx) override { expr.put(ctx, expr.get(ctx->NAME())); } @@ -229,7 +264,7 @@ public: void syntaxError(IRecognizer *recognizer, Token *offendingSymbol, size_t line, int charPositionInLine, const std::string &msg, std::exception_ptr e) override { - messages.push_back(msg); + messages.push_back("line " + to_string(line) + ":" + to_string(charPositionInLine) + ": " + msg); } }; @@ -266,6 +301,7 @@ LdScript LdScriptLoader::load(std::string path) { parser.addParseListener(&listener); LdErrorListener ldErrorListener; + parser.removeErrorListeners(); parser.addErrorListener(&ldErrorListener); auto file = parser.file(); -- cgit v1.2.3