00001
#include <ctype.h>
00002
#include <string.h>
00003
#include <stdio.h>
00004
#include <stdlib.h>
00005
#include <stack>
00006
#include <string>
00007
#include <antlr/AST.hpp>
00008
#include "AdaParser.hpp"
00009
#include "AdaTokenTypes.hpp"
00010
#include "adasupport.hpp"
00011
00012 #define eq !strcmp
00013
00014
using namespace std;
00015
00016
const RefAdaAST AdaAST::nullAdaAST(antlr::nullAST.get() );
00017
00018
using namespace std;
00019
00020 string
text (
const RefAdaAST& n)
00021 {
00022
if (n == 0 || n == AdaAST::nullAdaAST)
00023
return "";
00024 string retval;
00025
int type = n->getType();
00026
if (type == AdaTokenTypes::DOT) {
00027
const RefAdaAST& sibs = n->down ();
00028 retval =
text (sibs);
00029 retval.append (
".");
00030 retval.append (
text (sibs->right()));
00031 }
else {
00032 retval = n->getText();
00033 }
00034
00035
00036
00037
00038
00039
00040
00041
return retval;
00042 }
00043
00044 int txteq (RefAdaAST n1, RefAdaAST n2)
00045 {
00046
if (!n1 || !n2 || n1 == antlr::nullAST || n2 == antlr::nullAST)
00047
return 0;
00048
const char* s1 = n1->getText().c_str();
00049
const char* s2 = n2->getText().c_str();
00050
if (strcasecmp (s1, s2) != 0)
00051
return 0;
00052 n1 = n1->right ();
00053 n2 = n2->right ();
00054
if (!n1 || !n2 || n1 == antlr::nullAST || n2 == antlr::nullAST)
00055
return 1;
00056
if (n1->getType () == AdaTokenTypes::DOT)
00057
if (n2->getType () == AdaTokenTypes::DOT)
00058
return txteq (n1->right (), n2->right ());
00059
else
00060
return 0;
00061
else if (n2->getType () == AdaTokenTypes::DOT)
00062
return 0;
00063
return 1;
00064 }
00065
00066 std::stack<RefAdaAST>
defid_stack;
00067
00068 void AdaParser::push_def_id (
const RefAdaAST& defid)
00069 {
00070
#ifdef __DEBUG__
00071
string txt (
text (defid));
00072 printf (
"push_def_id: pushing %s\n", txt.c_str());
00073
#endif
00074
defid_stack.push (defid);
00075 }
00076
00077 const RefAdaAST&
AdaParser::pop_def_id ()
00078 {
00079
if (
defid_stack.size() == 0) {
00080 fprintf (stderr,
"pop_def_id() called on empty stack\n");
00081
00082
return AdaAST::nullAdaAST;
00083 }
00084
RefAdaAST& top =
defid_stack.top ();
00085
#ifdef __DEBUG__
00086
string txt (
text (top));
00087 printf (
"pop_def_id: popping %s\n", txt.c_str());
00088
#endif
00089
defid_stack.pop ();
00090
return top;
00091 }
00092
00093 bool AdaParser::end_id_matches_def_id (
const RefAdaAST& endid)
00094 {
00095
if (
defid_stack.size() == 0)
00096
return false;
00097
RefAdaAST& top =
defid_stack.top ();
00098 string defid (
text (top));
00099
defid_stack.pop();
00100
if (endid == 0 || endid == antlr::nullAST)
00101
return false;
00102 string txt (
text (endid));
00103
if (strcasecmp (defid.c_str (), txt.c_str ()) != 0) {
00104 string errtxt (
"End id ");
00105 errtxt.append (txt);
00106 errtxt.append (
" does not match ");
00107 errtxt.append (defid);
00108
reportError (errtxt);
00109
return false;
00110 }
00111
#ifdef __DEBUG__
00112
printf (
"end_id_matches_def_id: popped %s\n", txt.c_str());
00113
#endif
00114
return true;
00115 }
00116
00117 char *
strtolower (
char *string)
00118 {
00119
char *p = string;
00120
if (!p)
00121
return NULL;
00122
while (*p)
00123 {
00124
if (isupper (*p))
00125 *p = tolower (*p);
00126 p++;
00127 }
00128
return string;
00129 }
00130
00131 char *
extracted_operator (
const char *string)
00132 {
00133
int len = strlen (string);
00134
static char op[10];
00135
00136
if (len < 4 && len > 5 || *string !=
'"' || *(string +
len - 1) !=
'"')
00137
return NULL;
00138
00139 strcpy (op, string + 1);
00140 op[
len - 2] =
'\0';
00141
strtolower (op);
00142
return op;
00143 }
00144
00145 bool AdaParser::definable_operator (
const char *string)
00146 {
00147
char *op =
extracted_operator (string);
00148
if (op == NULL)
00149
return false;
00150
return
00151 (
eq (op,
"=") ||
00152
eq (op,
"<") ||
eq (op,
">") ||
00153
eq (op,
"<=") ||
eq (op,
">=") ||
00154
eq (op,
"&") ||
eq (op,
"**") ||
00155
eq (op,
"*") ||
eq (op,
"/") ||
eq (op,
"+") ||
eq (op,
"-") ||
00156
eq (op,
"abs") ||
eq (op,
"rem") ||
eq (op,
"mod") ||
00157
eq (op,
"and") ||
eq (op,
"or") ||
eq (op,
"xor") ||
eq (op,
"not"));
00158 }
00159
00160 bool AdaParser::is_operator_symbol (
const char *string)
00161 {
00162
char *op;
00163
if (
definable_operator (string))
00164
return true;
00165 op =
extracted_operator (string);
00166
return (
eq (op,
"/="));
00167 }
00168