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); }
void Expect(int t) { if (lex.token != t) lex.Error(lex.TokStr(t) + " expected, found: " + lex.TokStr()); lex.Next(); }
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); }
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(); }
void ExpectType(ValueType given, ValueType needed) { if (given != needed) { lex.Error(string("type ") + BaseTypeName(needed) + " required, " + BaseTypeName(given) + " given"); } }
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; }
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; } } } }
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; } }
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(); }
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; }
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(); } }
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(); } }
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(); }
void Gobble(TType t) { if (lex.token == t) lex.Next(); }