예제 #1
0
TEST(GrammarAnalyzer, Template0)
{
  int argc = 2;
  char argv0[128] = {0},argv1[128] = {0};
  strcpy(argv0,"tester");
  strcpy(argv1,"./test/GrammarSample/template_sample_0");
  char* argv[2] = {argv0,argv1};

	//analyze command line input
	CmdInputFactor::getInstance()->analyze(argc, argv);

	//now begin to analyze the files input from command line
	string toCompileFile = CmdInputFactor::getInstance()->getNextFile();

  Lex lex;

  lex.analyzeAFile(toCompileFile);

  LexRecList recList = lex.getRecList();

  GrammarAnalyzer grammar = GrammarAnalyzer(recList);

//  JZSetLoggerLevel(JZ_LOG_DEBUG|JZ_LOG_TRACE);
  uint32 ret = grammar.doAnalyze();
  JZSetLoggerLevel(JZ_LOG_TEST);

  ASSERT_EQ(eGrmErrNoError, ret);

}
예제 #2
0
    void Expect(int t)
    {
        if (lex.token != t)
            lex.Error(lex.TokStr(t) + " expected, found: " + lex.TokStr());

        lex.Next();
    }
예제 #3
0
    Value ParseElems(TType end, type_elem_t typeoff, int numelems = -1)  // Vector or struct.
    {
        Gobble(T_LINEFEED);
        vector<Value> elems;
        auto &ti = g_vm->GetTypeInfo(typeoff);

        if (lex.token == end) lex.Next();
        else
        {
            for (;;)
            {
                if ((int)elems.size() == numelems)
                {
                    ParseFactor(TYPE_ELEM_ANY).DECRT();  // Ignore the value.
                }
                else
                {
                    elems.push_back(ParseFactor(ti.t == V_VECTOR ? ti.subt : ti.elems[elems.size()]));
                }
                bool haslf = lex.token == T_LINEFEED;
                if (haslf) lex.Next();
                if (lex.token == end) break;
                if (!haslf) Expect(T_COMMA);
            }
            lex.Next();
        }

        if (numelems >= 0)
        {
            while ((int)elems.size() < numelems)
            {
                switch (ti.elems[elems.size()])
                {
                case V_INT:
                    elems.push_back(Value(0));
                    break;
                case V_FLOAT:
                    elems.push_back(Value(0.0f));
                    break;
                case V_NIL:
                    elems.push_back(Value());
                    break;
                default:
                    lex.Error("no default value possible for missing struct elements");
                }
            }
        }

        auto vec = g_vm->NewVector((int)elems.size(), (int)elems.size(), ti);
        vec->Inc();
        allocated.push_back(vec);
        int i = 0;
        for (auto &e : elems) vec->At(i++) = e;
        return Value(vec);
    }
예제 #4
0
파일: LRParser.cpp 프로젝트: spease/lr
bool LRParser::parse(Lex &i_lex)
{
  bool accepted=false;
  Symbol token = i_lex.pop();
  while(!m_stackState.empty())
  {
    LRState state=m_stackState.top();
    LRAction const &action=m_table.action(state, token);

#ifndef NDEBUG
    std::cout << "(" + std::to_string(state) + " + " + token.toString() + ") --> " + action.toString() << std::endl;
#endif

    if(action.isShift())
    {
      m_stackSymbol.push(token);
      m_stackState.push(action.state());
      token=i_lex.pop();
    }
    else if(action.isReduce())
    {
      Production const &p = action.production();
      Symbol const &leftSymbol = p.left()[0];
      SymbolList const &right = p.right();
      size_t const popCount = right.count();
      for(size_t x=0; x<popCount; ++x)
      {
        m_stackSymbol.pop();
        m_stackState.pop();
      }
      m_stackSymbol.push(leftSymbol);
      m_stackState.push(m_table.path(state, leftSymbol));
    }
    else if(action.isAccept())
    {
      accepted=true;
      break;
    }
    else
    {
      throw std::runtime_error("NOES!");
    }
  }

  return accepted;
}
const string DBMS::Delete (const string& tbname, Poliz& whereCl)
{
	int affR = 0;
	
	if (getTableStruct(tbname).numRecords == 0)
		return "OK. \n0 affected rows.\n\n";
	
	lockTable(tbname);
	
	moveToStart(tbname);
	
	Lex res;
	
	IntWrap ind = nameMap[tbname];
	if (!ind || deleted[ind])
		throw TableNotFound();
	
	while (!afterTableEnd(tbname))
	{
		evaluateExpr(tbname, whereCl);
		res = pst[0];
		if (res.get_type() != Lex_Bool)
		{
			throw TypeMismatch("WHERE-clause expected a boolean expression as it's argument.");
		}
		
		if (res.get_value()) // подходит под where-клаузу
		{
			tables[ind]->removeCurrentRecord();	
			++affR;
		}
		else
			moveNext(tbname);
	}
	
	moveToStart(tbname);
	
	unlockTable(tbname);
	
	stringstream s;
	s << "OK.\n" << affR << " affected rows.\n\n";
	
	return s.str();
}
예제 #6
0
 void ExpectType(ValueType given, ValueType needed)
 {
     if (given != needed)
     {
         lex.Error(string("type ") +
                   BaseTypeName(needed) +
                   " required, " +
                   BaseTypeName(given) +
                   " given");
     }
 }
예제 #7
0
int main(int argc, char *argv[])
{
    if(argc<3){
        cout<<"Modo de uso:"<<endl;
        cout<<"./AST fileIN fileOUT"<<endl;
    }
    else{
        File fp(argv[1], argv[2]);

        Lex *lex = new Lex();
        lex->startLex(fp);

        Syntactic syn(lex);
        syn.parser();
        fp.close();
        syn.show();

        Semantic sem;
        sem.parsing();
    }

    return 0;
}
예제 #8
0
    void Executer::start() {
        Lex curLex;
        while (curLex.getType() != LEX_FINISH) {
            curLex = getLex();
            switch (curLex.getType()) {
                case LEX_NUMBER:
                case LEX_STRING:
                case LEX_TRUE:
                case LEX_FALSE:
                case POLIZ_ADDRESS:
                    push(curLex);
                    break;
                case LEX_NAME: {
                    std::string value = curLex.getValue();
                    push(data[value]);
                    break;
                }
                case LEX_NOT: {
                    Lex val = pop();
                    push(Lex(LEX_STRING, val.getValue().length() ? "" : "1"));
                    break;
                }
                case LEX_ASSIGN: {
                    Lex val = pop(), address = pop();

                    data[address.getValue()] = val;
                    break;
                }
                case LEX_PLUS: {
                    Lex aStr = pop(), bStr = pop();

                    if (aStr.getType() == LEX_NUMBER && bStr.getType() == LEX_NUMBER) {
                        double a = std::atof(aStr.getValue().c_str()),
                                b = std::atof(bStr.getValue().c_str());

                        push(Lex(LEX_NUMBER, numToStr(a + b)));
                    }
                    else {
                        push(Lex(LEX_STRING, bStr.getValue() + aStr.getValue()));
                    }
                    break;
                }
                case LEX_MINUS: {
                    double a = lexToNum(pop()),
                            b = lexToNum(pop());

                    push(Lex(LEX_NUMBER, numToStr(b - a)));
                    break;
                }
                case LEX_MUL: {
                    double a = lexToNum(pop()),
                            b = lexToNum(pop());

                    push(Lex(LEX_NUMBER, numToStr(a * b)));
                    break;
                }
                case LEX_DIV: {
                    double a = lexToNum(pop()),
                            b = lexToNum(pop());

                    push(Lex(LEX_NUMBER, numToStr(b / a)));
                    break;
                }
                case POLIZ_GO: {
                    int pos = std::atoi(curLex.getValue().c_str());
                    goTo((size_t) pos);
                    break;
                }
                case POLIZ_FALSEGO: {
                    Lex condition = pop();
                    if (condition.getType() == LEX_STRING && condition.getValue() == "") {
                        int pos = std::atoi(curLex.getValue().c_str());
                        goTo((size_t) pos);
                        break;
                    }
                    if (condition.getType() == LEX_NUMBER)
                        if (condition.getValue() == "0") {
                            int pos = std::atoi(curLex.getValue().c_str());
                            goTo((size_t) pos);
                            break;
                        }
                    if (condition.getType() == LEX_FALSE) {
                        int pos = std::atoi(curLex.getValue().c_str());
                        goTo((size_t) pos);
                        break;
                    }
                    break;
                }
                case LEX_WRITE: {
                    std::cout << pop().getValue() << std::endl;
                    break;
                }
                case LEX_MORE: {
                    Lex a = pop(), b = pop();
                    if (a.getType() == LEX_FALSE && b.getType() == LEX_TRUE ||
                            a.getType() == LEX_NUMBER && b.getType() == LEX_NUMBER && lexToNum(a) < lexToNum(b))
                        push(Lex(LEX_TRUE, "1"));
                    else
                        push(Lex(LEX_FALSE, "0"));
                    break;
                }
                case LEX_MOREEQ: {
                    Lex a = pop(), b = pop();
                    if (a.getType() == LEX_FALSE || b.getType() == LEX_TRUE ||
                        a.getType() == LEX_NUMBER && b.getType() == LEX_NUMBER && lexToNum(a) <= lexToNum(b))
                        push(Lex(LEX_TRUE, "1"));
                    else
                        push(Lex(LEX_FALSE, "0"));
                    break;
                }

                case LEX_LESS: {
                    Lex a = pop(), b = pop();
                    if (b.getType() == LEX_FALSE && a.getType() == LEX_TRUE ||
                        a.getType() == LEX_NUMBER && b.getType() == LEX_NUMBER && lexToNum(a) > lexToNum(b))
                        push(Lex(LEX_TRUE, "1"));
                    else
                        push(Lex(LEX_FALSE, "0"));
                    break;
                }
                case LEX_LESSEQ: {
                    Lex a = pop(), b = pop();
                    if (b.getType() == LEX_FALSE || a.getType() == LEX_TRUE ||
                        a.getType() == LEX_NUMBER && b.getType() == LEX_NUMBER && lexToNum(a) >= lexToNum(b))
                        push(Lex(LEX_TRUE, "1"));
                    else
                        push(Lex(LEX_FALSE, "0"));
                    break;
                }
                case LEX_EQ: {
                    Lex a = pop(), b = pop();
                    if ((b.getType() == LEX_FALSE || b.getType() == LEX_TRUE) && a.getType() == b.getType() ||
                        a.getValue() == b.getValue())
                        push(Lex(LEX_TRUE, "1"));
                    else
                        push(Lex(LEX_FALSE, "0"));
                    break;
                }
                case LEX_NOTEQ: {
                    Lex a = pop(), b = pop();
                    if ((b.getType() == LEX_FALSE || b.getType() == LEX_TRUE) && a.getType() != b.getType() ||
                        a.getValue() != b.getValue())
                        push(Lex(LEX_TRUE, "1"));
                    else
                        push(Lex(LEX_FALSE, "0"));
                    break;
                }
            }
        }
    }
예제 #9
0
void convert_async(Lex& lex, const char *class_name, FILE *h, FILE *cpp)
{
	int		t, l;
	const char	*s, *e;
	Param		*params, *last, *next;
	bool		keep_params, timed_async, dynamic_event;

	keep_params = false;
	timed_async = false;
	dynamic_event = false;

	// we can have multiple dynamic as long as each have a different
	// function name; also, we need to mark them as being timed if
	// the timed flag is also specified
	lex.StartDynamic();

// first we parse the function
	// skip spaces
	do {
		t = lex.GetToken();
	} while(isspace(t) || t == '\n');
	if(t == '\0') {
eof:
		fprintf(stderr, "%s:%ld: error: EOF reached within an async declaration\n", lex.Filename(), lex.Line());
		g_errcnt++;
		return;
	}

	if(t != Lex::IDENTIFIER) {
		fprintf(stderr, "%s:%ld: error: async not followed by an identifier\n", lex.Filename(), lex.Line());
		g_errcnt++;
		return;
	}

	// we expect the name of the function
	s = lex.GetStart();
	e = lex.GetEnd();
	l = static_cast<int>(e - s);
	char* name = new char[l + 1];
	str_keeper sk(name);
	memcpy(name, s, l);
	name[l] = '\0';

	do {
		t = lex.GetToken();
	} while(isspace(t) || t == '\n');
	if(t == '\0') {
		goto eof;
	}

	if(t != '(') {
		fprintf(stderr, "%s:%ld: error: async function name not followed by (\n", lex.Filename(), lex.Line());
		g_errcnt++;
		return;
	}

	// now we read the parameters
	last = params = 0;
	do {
		t = get_param(lex, next);
		if(next != 0) {
			if(last != 0) {
				last->f_next = next;
			}
			if(params == 0) {
				params = next;
			}
			last = next;
		}
	} while(t != ')' && t != '\0');
	if(t == '\0') {
		goto eof;
	}

	// right after the ')' we can have a dynamic attribute!
	// the syntax is:
	//	__attribute__ ((dynamic[([<identifier>])]))
	do {
		 t = lex.GetToken();
	} while(isspace(t) || t == '\n');
	if(t != Lex::IDENTIFIER) {
		goto no_attribute;
	}
	s = lex.GetStart();
	e = lex.GetEnd();
	l = static_cast<int>(e - s);
	if(l != 13 || memcmp(s, "__attribute__", l) != 0) {
		fprintf(stderr, "%s:%ld: error: the keyword __attribute__ or = 0 was expected\n", lex.Filename(), lex.Line());
		g_errcnt++;
		goto skip_attr;
	}
	do {
		 t = lex.GetToken();
	} while(isspace(t) || t == '\n');
	if(t != '(') {
		fprintf(stderr, "%s:%ld: error: the keyword __attribute__ is expected to be followed by two '('\n", lex.Filename(), lex.Line());
		g_errcnt++;
		goto skip_attr;
	}
	do {
		 t = lex.GetToken();
	} while(isspace(t) || t == '\n');
	if(t != '(') {
		fprintf(stderr, "%s:%ld: error: the keyword __attribute__ is expected to be followed by two '('\n", lex.Filename(), lex.Line());
		g_errcnt++;
		goto skip_attr;
	}
more_attributes:
	do {
		 t = lex.GetToken();
	} while(isspace(t) || t == '\n');
	if(t != Lex::IDENTIFIER) {
		goto empty_attribute;
	}
	s = lex.GetStart();
	e = lex.GetEnd();
	l = static_cast<int>(e - s);
	if(l == 5 && memcmp(s, "timed", l) == 0) {
		timed_async = true;
		do {
			 t = lex.GetToken();
		} while(isspace(t) || t == '\n');
		goto empty_attribute;
	}
	else if(l == 13 && memcmp(s, "dynamic_event", l) == 0) {
		dynamic_event = true;
		do {
			 t = lex.GetToken();
		} while(isspace(t) || t == '\n');
		goto empty_attribute;
	}
	else if(l != 7 || memcmp(s, "dynamic", l) != 0) {
		fprintf(stderr, "%s:%ld: error: only one of 'timed' or 'dynamic' is supported as an attribute\n", lex.Filename(), lex.Line());
		g_errcnt++;
		do {
			 t = lex.GetToken();
		} while(isspace(t) || t == '\n');
		goto empty_attribute;
	}
	do {
		 t = lex.GetToken();
	} while(isspace(t) || t == '\n');
	if(t == '(') {
		// a user name may be specified!
		do {
			 t = lex.GetToken();
		} while(isspace(t) || t == '\n');
		if(t == Lex::IDENTIFIER) {
			s = lex.GetStart();
			e = lex.GetEnd();
			l = static_cast<int>(e - s);
			char* dname = new char[l + 1];
			str_keeper sk(dname);
			memcpy(dname, s, l);
			dname[l] = '\0';

// here we have (1) the name of the dynamic function
//		(2) the list of parameters for that function

			keep_params = lex.AddDynamic(params, dname, name);

			do {
				 t = lex.GetToken();
			} while(isspace(t) || t == '\n');
		}
		else {
			keep_params = lex.AddDynamic(params, "DynamicEvent", name);
		}
		if(t != ')') {
			fprintf(stderr, "%s:%ld: error: a ')' was expected after the dynamic attribute name\n", lex.Filename(), lex.Line());
			g_errcnt++;
			goto skip_attr;
		}
		do {
			 t = lex.GetToken();
		} while(isspace(t) || t == '\n');
	}
	else {
		keep_params = lex.AddDynamic(params, "DynamicEvent", name);
	}
empty_attribute:
	if(t == ',') {
		goto more_attributes;
	}
	if(t != ')') {
		fprintf(stderr, "%s:%ld: error: two ')' were expected to terminate the __attribute__\n", lex.Filename(), lex.Line());
		g_errcnt++;
		goto skip_attr;
	}
	do {
		 t = lex.GetToken();
	} while(isspace(t) || t == '\n');
	if(t != ')') {
		fprintf(stderr, "%s:%ld: error: two ')' were expected to terminate the __attribute__\n", lex.Filename(), lex.Line());
		g_errcnt++;
	}


skip_attr:
	// at the end we expect ' = 0'
	do {
		 t = lex.GetToken();
	} while(isspace(t) || t == '\n');
no_attribute:
	if(t != '=') {
		fprintf(stderr, "%s:%ld: error: = 0 is expected for all async functions\n", lex.Filename(), lex.Line());
		g_errcnt++;
	}
	else {
		do {
			t = lex.GetToken();
		} while(isspace(t) || t == '\n');
		if(t != Lex::NUMBER) {
			fprintf(stderr, "%s:%ld: error: = 0 is expected for all async functions\n", lex.Filename(), lex.Line());
			g_errcnt++;
		}
		else {
			// WARNING: we're not testing the number, we expect 0...
			t = lex.GetToken();
		}
	}

	if(t != ';') {
		fprintf(stderr, "%s:%ld: error: ; was expected at the end of a function declaration\n", lex.Filename(), lex.Line());
		g_errcnt++;
	}

// Finally, we got it all, let's convert the result...
	// declare the virtual function
	fprintf(h, "virtual void %s(", name);

	if(dynamic_event) {
		fprintf(h, "const molib::moName& __name");
	}

	next = params;
	if(next == 0) {
		if(!dynamic_event) {
			fprintf(h, "void");
		}
	}
	else {
		while(next != 0) {
			if(next != params) {
				fprintf(h, ", ");
			}
			fprintf(h, "%s", next->f_type);
			if(next->f_default_value != 0) {
				fprintf(h, " = %s", next->f_default_value);
			}
			next = next->f_next;
		}
	}
	fprintf(h, ") = 0;\n");

	// declare the static function
	fprintf(h, "\tstatic void Post%s(molib::moEventPipeBroadcast *__broadcast", name);
	fprintf(cpp, "void %s::Post%s(molib::moEventPipeBroadcast *__broadcast", class_name, name);

	if(dynamic_event) {
		fprintf(h, ", const molib::moName& __name");
		fprintf(cpp, ", const molib::moName& __name");
	}

	if(timed_async) {
		fprintf(h, ", time_t __time");
		fprintf(cpp, ", time_t __time");
	}

	next = params;
	while(next != 0) {
		fprintf(h, ", %s", next->f_type);
		fprintf(cpp, ", %s", next->f_type);
		if(next->f_default_value != 0) {
			fprintf(h, " = %s", next->f_default_value);
		}
		next = next->f_next;
	}
	fprintf(h, ");\n");

	fprintf(cpp,
")\n"
"{\n"
"\tclass __Event : public molib::moReceiversEvent\n"
"\t{\n"
"\tpublic:\n"
"\t\t__Event(");

	if(dynamic_event) {
		fprintf(cpp, "const molib::moName __name");
	}

	if(timed_async) {
		fprintf(cpp, "time_t __time");
	}

	next = params;
	if(next == 0) {
		if(!dynamic_event && !timed_async) {
			fprintf(cpp, "void");
		}
	}
	else {
		if(dynamic_event || timed_async) {
			fprintf(cpp, ", ");
		}
		fprintf(cpp, "%s", next->f_type);
		next = next->f_next;
		while(next != 0) {
			fprintf(cpp, ", %s", next->f_type);
			next = next->f_next;
		}
	}

	fprintf(cpp, ")\n"
"\t\t\t: molib::moReceiversEvent(\"%s\")",
		name);

	next = params;
	while(next != 0) {
		fprintf(cpp, ",\n"
"\t\t\t  f_%s(%s)", next->f_name, next->f_name);
		next = next->f_next;
	}

	if(dynamic_event) {
		fprintf(cpp, ",\n"
"\t\t\t  f___name(__name)");
	}

	fprintf(cpp, "\n"
"\t\t{\n");

	if(timed_async) {
		fprintf(cpp,
"\t\t\tSetTime(__time);\n"
);
	}

	fprintf(cpp,
"\t\t}\n"
"\t\t__Event(const __Event& event)\n"
"\t\t\t: molib::moReceiversEvent(event)");

	next = params;
	while(next != 0) {
		fprintf(cpp, ",\n"
"\t\t\t  f_%s(event.f_%s)", next->f_name, next->f_name);
		next = next->f_next;
	}

	if(dynamic_event) {
		fprintf(cpp, ",\n"
"\t\t\t  f___name(event.f___name)");
	}

	fprintf(cpp, "\n"
"\t\t{\n"
"\t\t}\n"
"\t\tconst char *GetClassName(void) const\n"
"\t\t{\n"
"\t\t\treturn \"molib::moBase::moEvent::__Event(%s)\";\n"
"\t\t}\n"
"\t\tvirtual molib::moEventSPtr Duplicate(void) const\n"
"\t\t{\n"
"\t\t\treturn new __Event(*this);\n"
"\t\t}\n"
"\t\tvirtual void SendToReceivers(const molib::moSortedList& receivers)\n"
"\t\t{\n"
"\t\t\tmolib::moList::position_t idx, max;\n"
"\t\t\t%s *r;\n"
"\t\t\tmax = receivers.Count();\n"
"\t\t\tfor(idx = 0; idx < max; ++idx) {\n"
"\t\t\t\tr = dynamic_cast<%s *>(receivers.Get(idx));\n"
"\t\t\t\tif(r != 0) {\n"
"\t\t\t\t\tr->%s(",
		name, class_name, class_name, name);

	if(dynamic_event) {
		fprintf(cpp, "f___name");
	}

	next = params;
	while(next != 0) {
		if(next != params || dynamic_event) {
			fprintf(cpp, ", ");
		}
		fprintf(cpp, "f_%s", next->f_name);
		next = next->f_next;
	}

	fprintf(cpp, ");\n"
"\t\t\t\t}\n"
"\t\t\t}\n"
"\t\t}\n");

	if(params != 0) {
		fprintf(cpp,
"\tprivate:\n");

		next = params;
		while(next != 0) {
			fprintf(cpp, "\t\t%s;\n", next->FType());
			next = next->f_next;
		}
	}

	if(dynamic_event) {
		fprintf(cpp, "\t\tmolib::moName f___name;\n");
	}

	fprintf(cpp,
"\t} __event");

	if(params != 0 || dynamic_event || timed_async) {
		fprintf(cpp, "(");

		if(dynamic_event) {
			fprintf(cpp, "__name");
		}

		if(timed_async) {
			fprintf(cpp, "%s__time", dynamic_event ? ", " : "");
		}

		next = params;
		if(next != 0) {
			if(dynamic_event || timed_async) {
				fprintf(cpp, ", ");
			}
			fprintf(cpp, "%s", next->f_name);
			next = next->f_next;
			while(next != 0) {
				fprintf(cpp, ", %s", next->f_name);
				next = next->f_next;
			}
		}

		fprintf(cpp, ")");
	}

	fprintf(cpp, ";\n"
"\t__broadcast->Post(__event);\n"
"}\n"
"\n");

	if(timed_async) {
		lex.TimedDynamic();
	}

	if(!keep_params) {
		delete params;
	}
}
예제 #10
0
void parse_class(Lex& lex, FILE *h, FILE *cpp)
{
	int		t, l, brackets;
	const char	*s, *e;

	do {
		t = lex.GetToken();
		lex.Write(h);
	} while(isspace(t) || t == '\n');
	if(t != Lex::IDENTIFIER) {
		// is it possible that we don't have an identifier after the keyword class?!
		fprintf(stderr, "%s:%ld: error: expected an identifier after the 'class' keyword\n", lex.Filename(), lex.Line());
		g_errcnt++;
		return;
	}
	// we got the class name!
	s = lex.GetStart();
	e = lex.GetEnd();
	l = static_cast<int>(e - s);
	char* class_name = new char[l + 1];
	str_keeper sk(class_name);
	memcpy(class_name, s, l);
	class_name[l] = '\0';

	brackets = 0;
	for(;;) {
		t = lex.GetToken();
		if(t == '\0') {
			// that's a big problem in the source file!
			return;
		}
		if(t == ';') {
			if(brackets == 0) {
				// in this special case, we don't have a full declaration
				// i.e.:   class Stuff;
				lex.Write(h);
				return;
			}
		}
		else if(t == '{') {
			brackets++;
		}
		else if(t == '}') {
			if(brackets == 0) {
				fprintf(stderr, "%s:%ld: error: could not find { in a class definition\n", lex.Filename(), lex.Line());
				g_errcnt++;
			}
			else {
				brackets--;
			}
			if(brackets == 0) {
				break;
			}
		}
		else if(t == Lex::IDENTIFIER) {
			s = lex.GetStart();
			e = lex.GetEnd();
			if(e - s == 5 && memcmp(s, "class", 5) == 0) {
				// warning: this is a recursive call...
				lex.Write(h);
				parse_class(lex, h, cpp);
			}
			else if(e - s == 5 && memcmp(s, "async", 5) == 0) {
				// we found an asynchroneous function
				convert_async(lex, class_name, h, cpp);
				continue;
			}
		}
		lex.Write(h);
	}
	// once a class is being closed, we need to put the dynamic
	// functions if any were defined
	Dynamic *d = lex.GetDynamic();
	if(d != 0) {
		fprintf(h, "public:\n");
		while(d != 0) {
			d->Output(lex, h, cpp, class_name);
			d = d->Next();
		}
	}
	lex.ClearDynamic();
	// we don't expect the lexical input to be messed up by
	// the Dynamic::Output() calls...
	lex.Write(h);
}
const string DBMS::Update(const string& tbname, const string& fdname, Poliz& expr, Poliz& whereCl)
{	
	int affR = 0;
	
	lockTable(tbname);
	
	if (getTableStruct(tbname).numRecords == 0)
		return "OK.\n0 affected rows.\n\n";
	moveToStart(tbname);
	
	Lex res;
	stringstream buf;
	ITBField* fdp;
	
	IntWrap ind = nameMap[tbname];
	if (!ind || deleted[ind])
		throw TableNotFound();
	
	while (!afterTableEnd(tbname))
	{
		evaluateExpr(tbname, whereCl);
		res = pst[0];
		if (res.get_type() != Lex_Bool)
		{
			throw TypeMismatch("WHERE-clause expected a boolean expression as it's argument.");
		}
		
		if (res.get_value()) // подходит под where-клаузу
		{
			++affR;
			pst.clear();
			evaluateExpr(tbname, expr);
			res = pst[0];
			
			fdp = getField(tbname, fdname);
			
			if (getFieldType(tbname, fdname) == Long)
			{
				if (res.get_type() != Lex_Num)
				{
					throw TypeMismatch("Type mismatch in UPDATE: LONG expression expected.");
				}
				buf << res.get_value() << endl;
				
				fdp->read(buf);
			}
			else
			{
				if (res.get_type() != Lex_Str)
				{
					throw TypeMismatch("Type mismatch in UPDATE: LONG expression expected.");
				}
				buf << res.get_str_value() << endl;
				
				fdp->read(buf);
			}
		}
		
		moveNext(tbname);
	}
	
	moveToStart(tbname);
	
	unlockTable(tbname);
	
	stringstream s;
	s << "OK.\n" << affR << " affected rows.\n\n";
	
	return s.str();
}
예제 #12
0
int get_param(Lex& lex, Param *& p)
{
	const char *s, *e;
	int t, paren;
	p = 0;
	for(;;) {
		do {
			t = lex.GetToken();
		} while(isspace(t) || t == '\n');
		if(t == '\0') {
			return t;
		}
		if(t == ',' || t == ')') {
			if(p == 0) {
				if(t == ',') {
					fprintf(stderr, "%s:%ld: error: , not expected here\n", lex.Filename(), lex.Line());
					g_errcnt++;
				}
				return t;
			}
			break;
		}
		if(p == 0) {
			p = new Param;
		}

		if(t == '=') {
			break;
		}
		s = lex.GetStart();
		if(t == '(') {
			p->f_function = true;
			paren = 1;
			do {
				t = lex.GetToken();
				if(t == '(') {
					paren++;
				}
				else if(t == ')') {
					paren--;
				}
			} while(paren != 0 && t != '\0');
		}
		e = lex.GetEnd();

		p->AppendType(s, static_cast<int>(e - s));
	}

// if the type is just 'void' and t is ')' then we don't want it
	if(strcmp(p->f_type, "void") == 0) {
		if(t != ')') {
			fprintf(stderr, "%s:%ld: error: invalid usage of type void\n", lex.Filename(), lex.Line());
			g_errcnt++;
			return t;
		}
		delete p;
		p = 0;
		return t;
	}

// compute the name of the parameter
	p->DefineName();

// special case of default values
	if(t == '=') {
		do {
			t = lex.GetToken();
		} while(isspace(t) || t == '\n');
		if(t == '\0') {
			return t;
		}
		if(t == ',') {
			fprintf(stderr, "%s:%ld: error: default value missing for parameter %s\n", lex.Filename(), lex.Line(), p->f_type);
			g_errcnt++;
			return t;
		}
		s = lex.GetStart();
		do {
			e = lex.GetEnd();
			t = lex.GetToken();
		} while(t != ',' && t != ')' && t != '\0');
		if(t == '\0') {
			return t;
		}
		p->SetDefaultValue(s, static_cast<long>(e - s));
	}

	return t;
}
예제 #13
0
    Value ParseFactor(type_elem_t typeoff)
    {
        auto &ti = g_vm->GetTypeInfo(typeoff);
        auto vt = ti.t;

        // TODO: also support boxed parsing as V_ANY.
        // means boxing int/float, deducing runtime type for V_VECTOR, and finding the existing struct.

        switch (lex.token)
        {
        case T_INT:
        {
            ExpectType(V_INT, vt);
            int i = atoi(lex.sattr.c_str());
            lex.Next();
            return Value(i);
        }

        case T_FLOAT:
        {
            ExpectType(V_FLOAT, vt);
            double f = atof(lex.sattr.c_str());
            lex.Next();
            return Value((float)f);
        }

        case T_STR:
        {
            ExpectType(V_STRING, vt);
            string s = lex.sattr;
            lex.Next();
            auto str = g_vm->NewString(s);
            str->Inc();
            allocated.push_back(str);
            return Value(str);
        }

        case T_NIL:
        {
            ExpectType(V_NIL, vt);
            lex.Next();
            return Value();
        }

        case T_MINUS:
        {
            lex.Next();
            Value v = ParseFactor(typeoff);
            switch (typeoff)
            {
            case TYPE_ELEM_INT:
                v.setival(v.ival() * -1);
                break;
            case TYPE_ELEM_FLOAT:
                v.setfval(v.fval() * -1);
                break;
            default:
                lex.Error("unary minus: numeric value expected");
            }
            return v;
        }

        case T_LEFTBRACKET:
        {
            ExpectType(V_VECTOR, vt);
            lex.Next();
            return ParseElems(T_RIGHTBRACKET, typeoff);
        }

        case T_IDENT:
        {
            ExpectType(V_STRUCT, vt);
            string sname = lex.sattr;
            lex.Next();
            Expect(T_LEFTCURLY);
            auto name = g_vm->StructName(ti);
            if (name != sname) lex.Error("struct type " + name + " required, " + sname + " given");
            return ParseElems(T_RIGHTCURLY, typeoff, ti.len);
        }

        default:
            lex.Error("illegal start of expression: " + lex.TokStr());
            return Value();
        }
    }
예제 #14
0
    Value ParseFactor()
    {
        switch (lex.token)
        {
            case 'INT': { int i    = atoi(lex.sattr.c_str()); lex.Next(); return Value(i); }
            case 'FLT': { double f = atof(lex.sattr.c_str()); lex.Next(); return Value((float)f); }
            case 'STR': { string s = lex.sattr;               lex.Next(); auto str = g_vm->NewString(s); allocated.push_back(str); return Value(str); }     
            case 'NIL': {                                     lex.Next(); return Value(0, V_NIL);    }

            case '-':
            {
                lex.Next(); 
                Value v = ParseFactor();
                switch (v.type)
                {
                    case V_INT:   v.ival *= -1; break;
                    case V_FLOAT: v.fval *= -1; break;
                    default: lex.Error("numeric value expected");
                }
                return v;
            }

            case '[':
            {
                lex.Next();
                Gobble('LF');
                vector<Value> elems;
                if (lex.token == ']') lex.Next();
                else
                {
                    for (;;)
                    {
                        elems.push_back(ParseFactor());
                        bool haslf = lex.token == 'LF';
                        if (haslf) lex.Next();
                        if (lex.token == ']') break;
                        if (!haslf) Expect(',');
                    }
                    lex.Next();
                }

                int type = -1;
                if (lex.token == ':')
                {
                    lex.Next();
                    string sname = lex.sattr;
                    Expect('ID');
                    size_t reqargs = 0;
                    int idx = g_vm->StructIdx(sname, reqargs);
                    if (idx >= 0)   // if unknown type, becomes regular vector
                    {
                        while (elems.size() < reqargs) { elems.push_back(Value(0, V_NIL)); }         // pad with NIL if current type has more fields
                        while (elems.size() > reqargs) { elems.back().DEC(); elems.pop_back(); }     // drop elements if current type has less fields
                        type = idx;
                    }
                }

                auto vec = g_vm->NewVector(elems.size(), type);
                allocated.push_back(vec);
                for (auto &e : elems) vec->push(e.INC());
                return Value(vec);
            }

            default:
                lex.Error("illegal start of expression: " + lex.TokStr());
                return Value();
        }
    }
예제 #15
0
 void Gobble(int t)
 {
     if (lex.token == t) lex.Next();
 }
const string DBMS::Select(const string& tbname, vector<string>& fdList, Poliz& whereCl)
{
	stringstream result;
	
	if (fdList.size() == 1 && fdList[0] == "*")
	{
		fdList = getTableStruct(tbname).names;
	}
	
	
	
	Table* tab = new Table("from "+tbname);
	tab->tbstr.names = fdList;
	tab->tbstr.numFields = fdList.size();
	tab->tbstr.numRecords = 0;
	
	if (getTableStruct(tbname).numRecords == 0)
	{
		result << *tab << endl << "OK." << endl;
		return result.str();
	}
	moveToStart(tbname);
	
	IntWrap ind;
	
	for (int i = 0; i < tab->tbstr.numFields; ++i)
	{
		tab->tbstr.types.push_back( getFieldType(tbname, fdList[i]) );
		tab->tbstr.nameMap[fdList[i]] = i;
	}
	
	Lex res;
	stringstream buf;
	ITBField* buf_fd;
	
	
	while (!afterTableEnd(tbname))
	{
		evaluateExpr(tbname, whereCl);
		res = pst[0];
		if (res.get_type() != Lex_Bool)
		{
			throw TypeMismatch("WHERE-clause expected a boolean expression as it's argument.");
		}
		
		if (res.get_value()) // подходит под where-клаузу
		{
			tab->records.push_back( new ITBField* [tab->tbstr.numFields] );
			
			for (int k = 0; k < tab->tbstr.numFields; ++k)
			{
				if (tab->tbstr.types[k] == Long)
				{
					(*(tab->records.rbegin()))[k] = new TBFieldLong();
				}
				else
				{
					(*(tab->records.rbegin()))[k] = new TBFieldText();
				}
				
				IntWrap ii = tab->tbstr.nameMap[fdList[k]];
				if (!ii)
				{
					throw FieldNotFound();
				}
				
				buf_fd = getField(tbname, tab->tbstr.names[ii]);
				
				buf_fd->write(buf, false);
				buf << endl;
				
				(*(tab->records.rbegin()))[k]->read(buf);
				
			}
			
			++(tab->tbstr.numRecords);
			
			if (tab->currentId == -1)
			{
				tab->currentId = 0;
				tab->currentRecord = tab->records.begin();
			}
		}
		
		moveNext(tbname);
	}
	
	result << *tab << endl << "OK.\n\n" << endl;
	
	moveToStart(tbname);
	
	return result.str();
}
예제 #17
0
 void Gobble(TType t)
 {
     if (lex.token == t) lex.Next();
 }