[c++] jak rozwiazac bledy kompilacji

0

Witam!

Mam do uzupełenienia na zajęcia kod wirtualnej maszyny. Wszystko fajnie tylko pojawia się problem przy kompilacji. Wygląda następująco:

g++ -g -Wall -c -o analyzer.o analyzer.cpp
analyzer.cpp: In function ?const char* get_double(const char*, double&)?:
analyzer.cpp:182: error: ?strtod? was not declared in this scope
analyzer.cpp: In function ?const char* gettoken(const char*, tokentype&, tokenval&)?:
analyzer.cpp:227: error: ?errno? was not declared in this scope
analyzer.cpp:228: error: ?strtoll? was not declared in this scope
analyzer.cpp: In function ?const char* extract_address(const char*, argaddr&, bool)?:
analyzer.cpp:310: error: ?INT_MIN? was not declared in this scope
analyzer.cpp:310: error: ?INT_MAX? was not declared in this scope
analyzer.cpp:333: error: ?INT_MIN? was not declared in this scope
analyzer.cpp:333: error: ?INT_MAX? was not declared in this scope
make: *** [analyzer.o] Error 1

Byłabym wdzięczna gdyby mógł ktoś wyjaśnić dlaczego pojawiają się te błędy skoro wg mnie wszystko gra (ale pewnie się mylę)

Przedstawiam poniżej kod jednego z plików:

#include <ctype.h>
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <errno.h>


using namespace std;

#include "vm.h"

unsigned int pass;

map < string, opcode > opcode_table;

/*
* Instruction format:
* add.i #bp+7,    7,     *bp-6
*       immediate direct indirect 
* call #183
*/
//tablica instrukcji,struktury typu opcode_info
struct opcode_info opcodes[] = {
  {"", OC_NONE, AT_NONE, h_none, s_none},
  {"mov", OC_MOV, AT_NONE, h_mov, s_twoarg},
  {"add", OC_ADD, AT_NONE, h_add, s_threearg},
  {"sub", OC_SUB, AT_NONE, h_sub, s_threearg},
  {"mul", OC_MUL, AT_NONE, h_mul, s_threearg},
  {"mod", OC_MOD, AT_INTEGER, h_mod, s_threearg},
  {"div", OC_DIV, AT_INTEGER, h_div, s_threearg},
  {"and", OC_AND, AT_NONE, h_and, s_threearg},
  {"or", OC_OR, AT_NONE, h_or, s_threearg},
  {"call", OC_CALL, AT_INTEGER, h_call, s_oneinteger},
  {"enter", OC_ENTER, AT_INTEGER, h_enter, s_oneinteger},
  {"leave", OC_LEAVE, AT_INTEGER, h_leave, s_none},
  {"return", OC_RETURN, AT_INTEGER, h_return, s_none},
  {"write", OC_WRITE, AT_NONE, h_write, s_onearg},
  {"read", OC_READ, AT_NONE, h_read, s_onearg},
  {"jump", OC_JUMP, AT_INTEGER, h_jump, s_oneinteger},
  {"je", OC_JE, AT_NONE, h_je, s_threearg_jump},
  {"jge", OC_JGE, AT_NONE, h_jge, s_threearg_jump},
  {"jg", OC_JG, AT_NONE, h_jg, s_threearg_jump},
  {"jl", OC_JL, AT_NONE, h_jl, s_threearg_jump},
  {"jle", OC_JLE, AT_NONE, h_jle, s_threearg_jump},
  {"inttoreal", OC_INTTOREAL, AT_INTEGER, h_inttoreal, s_twoarg},
  {"realtoint", OC_REALTOINT, AT_REAL, h_realtoint, s_twoarg},
  {"push", OC_PUSH, AT_NONE, h_push, s_onearg},
  {"incsp", OC_INCSP, AT_INTEGER, h_incsp, s_oneinteger},
  {"exit", OC_EXIT, AT_INTEGER, h_none, s_none},
};


vector <void (*) (const instruction &) >dispatch_table(OC_FINAL);
vector <void (*) (const instruction &) >syntax_table(OC_FINAL);
vector <argtype > default_argtype_table(OC_FINAL);


void
setup_opcodes ()
{
  for (unsigned int i = 0; i < sizeof (opcodes) / sizeof (opcodes[0]); i++)
    {
      opcode_table[opcodes[i].name] = opcodes[i].oc;
      dispatch_table[opcodes[i].oc] = opcodes[i].oh;
      syntax_table[opcodes[i].oc] = opcodes[i].sh;
      default_argtype_table[opcodes[i].oc] = opcodes[i].at;
    };
};

vector < instruction > instructions;
map < string, UINT >symtab;
UINT current_address = 0;


#define skipws(s) do {while (isspace(*(s))) (s)++;} while (0)

/*
* Read the label from the input line s
* Label is empty, if there's no label in the line
* Return the pointer to the first character after the label
* Syntax_error exception is thrown in case of syntax error
*/

const char *
extract_label (const char *s, string & label)
{
  const char *os = s;
  label.assign ("");
  skipws (s);
  const char *begword = s;
  while (isalnum (*s))
    s++;
  const char *endword = s;
  skipws (s);
  if (*s == ':')		//we have a label
    {
      if (endword == begword)
	throw syntax_error ("Empty label");
      if (!isalpha (*begword))
	throw syntax_error ("Label starting with number");
      label.assign (begword, endword);
      if(label=="bp")
        throw syntax_error("Reserved word: 'bp' used as a label");
      return s + 1;
    }
  return os;
}


/*
* Read the opcode and operand size from the input line s
* It is assumed, that the label is removed from s
* Return the pointer to the first non-ws character 
* after the opcode and operand size modifier
* Syntax_error exception is thrown in case of syntax error
*/
const char *
extract_instr (const char *s, opcode & oc, argtype & at)
{
  at = AT_NONE;
  oc = OC_NONE;
  skipws (s);
  const char *begword = s;
  while (isalpha (*s))
    s++;
  const char *endword = s;
  skipws (s);
  if (begword == endword)
    return s;
  string op (begword, endword);
  map < string, opcode >::iterator oi;
  if ((oi = opcode_table.find (op)) == opcode_table.end ())
    throw syntax_error ("Unknown opcode");
  oc = oi->second;
  if(oc>=OC_FINAL)
    throw("Internal error: invalid opcode");
  at = default_argtype_table[oc];

  if (*s == '.')		//we have reached the end of an opcode
    {
      s++;
      skipws (s);
      if (*s == 'r')
	at = AT_REAL;
      else if (*s == 'i')
	at = AT_INTEGER;
      else
	throw syntax_error ("Unknown operand type specifier");
      s++;
    };
  skipws (s);
  return s;
};

/*
* Lookup a label in the symbol table
* Return -1 if symbol not present
*/
long long
lookup (const string & val)
{
  map < string, UINT >::iterator i;
  i = symtab.find (val);
  if (i == symtab.end ())
    return -1;
  else
    return i->second;
}

/*
* Get double literal from input line.
* Skip leading and trailing whitespace.
* Throw exception if number nonexistent or misformed.
*/

const char *
get_double (const char *s, double &d)
{
  char *ns;
  d = strtod (s, &ns);
  if (s != ns)
    s = ns;
  else
    throw syntax_error ("Real literal not found or misformed");
  skipws (s);
  return s;
};


bool
issep (char c)
{
  if ((c == ',') || (c == '\0'))
    return true;
  else
    return false;
};

enum tokentype
{ TT_CHAR, TT_INTEGER, TT_ID, TT_NONE };

struct tokenval
{
  string s;
  union
  {
    long long i;
    char c;
  };
};

/*
* Get next token from string s
* Skip leading and trailing whitespace
* Return pointer to the next non-ws character in s after the token
*/

const char *
gettoken (const char *s, tokentype & token, tokenval & val)
{
  skipws (s);
  if (isdigit (*s) || (*s == '+') || (*s == '-'))
    {
      char *ns;
      errno=0;
      long long v=strtoll(s, &ns, 0);
      if ((errno!=0) || (ns == s))
	{
	  //not a number
	  val.c = *s;
	  token = TT_CHAR;
	  skipws (s);
	  return s;
	};
      val.i = v;
      s = ns;
      skipws (s);
      token = TT_INTEGER;
      return s;
    }
  if (isalpha (*s))
    {
      const char *begin = s;
      while (isalnum (*s))
	s++;
      val.s.assign (begin, s);
      skipws (s);
      token = TT_ID;
      return s;
    };
  if (issep (*s))
    {
      token = TT_NONE;
      return s;
    }
  val.c = *s;
  token = TT_CHAR;
  skipws (s);
  return s;
};

/*
* Read the argument from the input line s
* It is assumed, that we are after the separator
* Return the pointer to the separator after the operand
* Syntax_error exception is thrown in case of syntax error
* Realmode indicates, whether the operand type 
* is real (true) or integer (false)
*/
const char *
extract_address (const char *s, argaddr & aa, bool realmode)
{
  aa.am = AM_DIRECT;
  aa.br = BR_NONE;
  skipws (s);
  if (*s == '#')
    {
      aa.am = AM_IMMEDIATE;
      s++;
    }
  else if (*s == '*')
    {
      aa.am = AM_INDIRECT;
      s++;
    }
  skipws (s);
/*
* Acceptable address formats:
* bp
* bp + number
* bp - number
* int_number
* real_number (only iff realmode==true and immediate mode used)
* label
*/
  if ((aa.am == AM_IMMEDIATE) && realmode)
    {
      s = get_double (s, aa.realval);
      if (!issep (*s))
	throw syntax_error ("Garbage after real literal");
      return s;
    }
  tokentype tt;
  tokenval tv;
  s = gettoken (s, tt, tv);
  if (tt == TT_INTEGER)
    {
     if((tv.i<IMIN) || (tv.i>IMAX))
       throw syntax_error("Number too big");
      aa.intval = tv.i;
      if (!issep (*s))
	throw syntax_error ("Garbage after literal");
      return s;
    }
  if (tt == TT_ID)
    {
      if (tv.s == "bp")
	{
	  aa.br = BR_BP;
	  if ((*s == '+') || (*s == '-'))
	    {
	      int mult = (*s == '+') ? 1 : -1;
	      s++;
	      skipws(s);
	      if ((*s=='+') || (*s=='-'))
	        throw syntax_error("Duplicate sign after 'bp +/-'");
	      s = gettoken (s, tt, tv);
	      if (tt == TT_INTEGER)
		{
		  long long t=tv.i*mult;
                  if((t<IMIN) || (t>IMAX))
                    throw syntax_error("Number too big");
		  aa.intval = t;
		  if (!issep (*s))
		    {
		      throw syntax_error ("Garbage after literal");
		    }
		  return s;
		}
	      else
		throw syntax_error ("Garbage after 'bp+' or 'bp-'");
	    }
	  else if (issep (*s))
	    {
	      aa.intval = 0;
	      return s;
	    }
	  else
	    {
	      throw syntax_error ("Invalid character after 'bp+' or 'bp-'");
	    }
	}
      else			//single label
	{
	  if (pass == 1)
	    {
	      long long n = lookup (tv.s);
	      if (n < 0)
		{
		  throw syntax_error ("Unknown label");
		}
	      else
		aa.intval = n;
	    };
	  if (!issep (*s))
	    throw syntax_error ("Garbage after label");
	  return s;
	};
    }
  if ((tt == TT_NONE) && (aa.am == AM_DIRECT))
    aa.am = AM_NONE;
  else
    {
      throw syntax_error ("Garbage after address mode modifier");
    }
  return s;
};

/*
* Analyze entire line of code
* Comments are already stripped from the line
*/

void
analyze (const char *s)
{
  instruction instr;
  instr.args[0].am = AM_NONE;
  instr.args[1].am = AM_NONE;
  instr.args[2].am = AM_NONE;
  string label;
  s = extract_label (s, label);
  s = extract_instr (s, instr.oc, instr.at);
  bool realmode;
  if (instr.at == AT_REAL)
    realmode = true;
  else
    realmode = false;
  if (instr.oc != OC_NONE)
    {
      /* beware: inttoreal and realtoint are special cases 
       * with respect to the operand types - need to specify them explicitly */    
      s = extract_address (s, instr.args[0], realmode);
      if (*s == ',')
	{
	  if (instr.args[0].am == AM_NONE)
	    throw syntax_error ("Empty first operand");
	  s++;
	  s = extract_address (s, instr.args[1], realmode);
	  if (instr.args[1].am == AM_NONE)
	    throw syntax_error ("Empty second operand");
	  if (*s == ',')
	    {
	      s++;
	      if ((instr.oc != OC_JE) && (instr.oc != OC_JGE) && (instr.oc != OC_JG) && (instr.oc != OC_JLE) && (instr.oc != OC_JE))	//jumps are special - last arg always integer
		s = extract_address (s, instr.args[2], realmode);
	      else
		s = extract_address (s, instr.args[2], false);
	      if (instr.args[2].am == AM_NONE)
		throw syntax_error ("Empty third operand");
	    }
	  else if (*s != '\0')
	    {
	      throw syntax_error ("Wrong separator");
	    }

	}
      else if (*s != '\0')
	{
	  throw syntax_error ("Wrong separator");
	}
    }
  else				//OC_NONE
    {
      if (*s)
	throw syntax_error ("Invalid opcode");
    }
  if (pass == 0)
    if (label.length () != 0)
      {
	if (lookup (label) >= 0)
	  {
	    throw syntax_error (string ("Duplicate label ") + label);
	  }
	symtab[label] = current_address;
      };
  if (instr.oc != OC_NONE)
    {
      if (instr.at == AT_NONE)
	throw syntax_error ("No argument type specified");
      if(instr.oc>=OC_FINAL)
        throw syntax_error("Internal error: invalid opcode");
      syntax_table[instr.oc](instr);
      if (pass == 1)
	instructions[current_address] = instr;
      current_address++;
    }

}
0

http://cplusplus.com/ - wrzuć w wyszukiwarkę klamoty, których nie znajduje i zobacz jakie nagłówki są konieczne. Oczywiście kod nie jest Twój...

0

No kod nie jest mój oczywiście, że nie. Dostałam taki jak widać od wykładowcy i dopisałam tylko kilka brakujących instrukcji. Te errory pojawiały się na samym początku kmpilacji takiego "gołego" kodu.

0

Ja k... p...lę - żeby dostać takiego gotowca i se k@#@ includów nie potrafić dopisać [sciana]

inna sprawa - nie zdziwię się, jak plik "vm.h" gdzieś ci uciekł, znaczy nawet skopiowany do jednego katalogu ze źródłem nie jest [sciana]

0

Przepraszam najmocniej ale plik vm.h znajduje sie w katalogu z resztą plików a nagłówki do funkcji o które pluję się kompilator sa już dopisane. Jakbym umiała sobie z problemem poradzić rzecz jasna bym nie pytała.

0

są ?
nie widze nigdzie (c)stdlib.. http://www.cplusplus.com/reference/clibrary/cstdlib/strtod.html http://linux.die.net/man/3/strtoll http://linux.die.net/man/3/strtoll

INT_MAX/MIN siedza z kolei w (to juz moglas akurat nie znalezc) limits

1 użytkowników online, w tym zalogowanych: 0, gości: 1