#include #include #include #include #include #include #include #include "AdaParser.hpp" #include "AdaTokenTypes.hpp" #include "adasupport.hpp" #define eq !strcmp using namespace std; const RefAdaAST AdaAST::nullAdaAST(antlr::nullAST.get() ); using namespace std; string text (const RefAdaAST& n) { if (n == 0 || n == AdaAST::nullAdaAST) return ""; string retval; int type = n->getType(); if (type == AdaTokenTypes::DOT) { const RefAdaAST& sibs = n->down (); retval = text (sibs); retval.append ("."); retval.append (text (sibs->right())); } else { retval = n->getText(); } /* const RefAdaAST& r = n->right(); if (r != 0 && r->getType () == AdaTokenTypes::DOT) { retval.append ("."); retval.append (text (r->right())); } */ return retval; } int txteq (RefAdaAST n1, RefAdaAST n2) { if (!n1 || !n2 || n1 == antlr::nullAST || n2 == antlr::nullAST) return 0; const char* s1 = n1->getText().c_str(); const char* s2 = n2->getText().c_str(); if (strcasecmp (s1, s2) != 0) return 0; n1 = n1->right (); n2 = n2->right (); if (!n1 || !n2 || n1 == antlr::nullAST || n2 == antlr::nullAST) return 1; if (n1->getType () == AdaTokenTypes::DOT) if (n2->getType () == AdaTokenTypes::DOT) return txteq (n1->right (), n2->right ()); else return 0; else if (n2->getType () == AdaTokenTypes::DOT) return 0; return 1; } std::stack defid_stack; void AdaParser::push_def_id (const RefAdaAST& defid) { #ifdef __DEBUG__ string txt (text (defid)); printf ("push_def_id: pushing %s\n", txt.c_str()); #endif defid_stack.push (defid); } const RefAdaAST& AdaParser::pop_def_id () { if (defid_stack.size() == 0) { fprintf (stderr, "pop_def_id() called on empty stack\n"); // return static_cast(antlr::nullAST); return AdaAST::nullAdaAST; } RefAdaAST& top = defid_stack.top (); #ifdef __DEBUG__ string txt (text (top)); printf ("pop_def_id: popping %s\n", txt.c_str()); #endif defid_stack.pop (); return top; } bool AdaParser::end_id_matches_def_id (const RefAdaAST& endid) { if (defid_stack.size() == 0) return false; RefAdaAST& top = defid_stack.top (); string defid (text (top)); defid_stack.pop(); if (endid == 0 || endid == antlr::nullAST) return false; string txt (text (endid)); if (strcasecmp (defid.c_str (), txt.c_str ()) != 0) { string errtxt ("End id "); errtxt.append (txt); errtxt.append (" does not match "); errtxt.append (defid); reportError (errtxt); return false; } #ifdef __DEBUG__ printf ("end_id_matches_def_id: popped %s\n", txt.c_str()); #endif return true; } char * strtolower (char *string) { char *p = string; if (!p) return NULL; while (*p) { if (isupper (*p)) *p = tolower (*p); p++; } return string; } char * extracted_operator (const char *string) { int len = strlen (string); static char op[10]; if (len < 4 && len > 5 || *string != '"' || *(string + len - 1) != '"') return NULL; strcpy (op, string + 1); op[len - 2] = '\0'; /* discard ending quotation mark */ strtolower (op); return op; } bool AdaParser::definable_operator (const char *string) { // operator_symbol sans "/=" char *op = extracted_operator (string); if (op == NULL) return false; return (eq (op, "=") || eq (op, "<") || eq (op, ">") || eq (op, "<=") || eq (op, ">=") || eq (op, "&") || eq (op, "**") || eq (op, "*") || eq (op, "/") || eq (op, "+") || eq (op, "-") || eq (op, "abs") || eq (op, "rem") || eq (op, "mod") || eq (op, "and") || eq (op, "or") || eq (op, "xor") || eq (op, "not")); } bool AdaParser::is_operator_symbol (const char *string) { char *op; if (definable_operator (string)) return true; op = extracted_operator (string); return (eq (op, "/=")); }