int main(int argc, char** argv){ int opt; int r; AST_Class modelica_class; while((opt = getopt(argc, argv, "d:")) != -1){ switch(opt){ case 'd': if(optarg != NULL && isDebugParam(optarg)){ debugInit(optarg); }else{ ERROR("Command line option d requires an argument\n"); } break; } } if(optind < argc){ modelica_class = parseClass(argv[optind],&r); }else{ /* si no se especifico un archivo leo de stdin*/ modelica_class = parseClass("", &r); } if(r!=0){ return -1; } /* creamos la clase MicroModelica */ TypeSymbolTable ty = newTypeSymbolTable(); MMO_Class mmo_class = newMMO_Class(modelica_class, ty); ReducedGraphBuilder *gb = new ReducedGraphBuilder(mmo_class); CausalizationGraph g = gb->makeGraph(); //para debuggeo: crea archivo grafo.dot if(debugIsEnabled('g')){ GraphPrinter gp(g); gp.printGraph(); } CausalizationStrategy2 *cs = new CausalizationStrategy2(g); if(cs->causalize()){ if(debugIsEnabled('c')){ cout << "Result of causalization (variable, [range,] equationID):" << endl; cs->print(); } }else{ //si no anduvo, probamos con la estrategia clasica DEBUG('c', "Executing the classic strategy\n"); CausalizationStrategy *cs_clasica = new CausalizationStrategy(mmo_class); AST_ClassList cl = newAST_ClassList(); cs_clasica->causalize(mmo_class->name(), cl); DEBUG('c', "Causalized Equations:\n"); MMO_EquationList causalEqs = mmo_class->getEquations(); MMO_EquationListIterator causalEqsIter; foreach(causalEqsIter, causalEqs) { DEBUG('c', "%s", current_element(causalEqsIter)->print().c_str()); } }
static void findEiffelTags (void) { tokenInfo *const token = newToken (); while (findKeyword (token, KEYWORD_class)) parseClass (token); deleteToken (token); }
CObject *MfcArchive::readClass() { bool isCopyReturned; CObject *res = parseClass(&isCopyReturned); if (res && !isCopyReturned) res->load(*this); return res; }
bool TypeInfo::parseString(const QString &str) { QStringList fields = str.split(",,"); if(fields.size() != 3) return false; class_ = parseClass(fields[0]); name_ = fields[1]; type_ = fields[2]; return true; }
static void findEiffelTags (void) { tokenInfo *const token = newToken (); exception_t exception; exception = (exception_t) (setjmp (Exception)); while (exception == ExceptionNone) { findKeyword (token, KEYWORD_class); parseClass (token); } deleteToken (token); }
static void scanFile(const QString& in) { QList<Prop> props; QList<Proc> procs; QRegExp re("@@ ([^\\n]*)"); int gpos = 0; QString className; for (;;) { int rv = re.indexIn(in, gpos); if (rv == -1) { if (!className.isEmpty()) parseClass(className, in.mid(gpos, in.size() - gpos)); break; } int next = rv + re.matchedLength(); if (gpos) parseClass(className, in.mid(gpos, next-gpos)); className = re.cap(1).simplified(); gpos = next; } }
/// tokenize first, then parse with recursive descent bool PSClass::parse(ifstream &in) { // remove comments bool result=tokenize(in); // print tokens cout << "--------start of token--------" <<endl; cout << tokens.str() <<endl; cout << "---------end of token---------" <<endl; istringstream token(tokens.str()); // parseClass token >> nextToken; result=result && parseClass(token); return result; }
NFAUNode * WCPattern::parse(const bool inParen, const bool inOr, NFAUNode ** end) { NFAUNode * start, *cur, *next = NULL; CMString t; int grc = groupCount++; bool inv, quo; bool ahead = 0, pos = 0, noncap = 0, indep = 0; unsigned long oldFlags = flags; if (inParen) { if (pattern[curInd] == '?') { ++curInd; --groupCount; if (pattern[curInd] == ':') { noncap = 1; ++curInd; grc = --nonCapGroupCount; } else if (pattern[curInd] == '=') { ++curInd; ahead = 1; pos = 1; } else if (pattern[curInd] == '!') { ++curInd; ahead = 1; pos = 0; } else if (pattern.Mid(curInd, 2) == L"<=") { curInd += 2; return parseBehind(1, end); } else if (pattern.Mid(curInd, 2) == L"<!") { curInd += 2; return parseBehind(0, end); } else if (pattern[curInd] == '>') { ++curInd; indep = 1; } else { bool negate = false, done = false; while (!done) { if (curInd >= pattern.GetLength()) { raiseError(); return NULL; } else if (negate) { switch (pattern[curInd]) { case 'i': flags &= ~WCPattern::CASE_INSENSITIVE; break; case 'd': flags &= ~WCPattern::UNIX_LINE_MODE; break; case 'm': flags &= ~WCPattern::MULTILINE_MATCHING; break; case 's': flags &= ~WCPattern::DOT_MATCHES_ALL; break; case ':': done = true; break; case ')': ++curInd; *end = registerNode(new NFALookBehindUNode(L"", true)); return *end; case '-': default: raiseError(); return NULL; } } else { switch (pattern[curInd]) { case 'i': flags |= WCPattern::CASE_INSENSITIVE; break; case 'd': flags |= WCPattern::UNIX_LINE_MODE; break; case 'm': flags |= WCPattern::MULTILINE_MATCHING; break; case 's': flags |= WCPattern::DOT_MATCHES_ALL; break; case ':': done = true; break; case '-': negate = true; break; case ')': ++curInd; *end = registerNode(new NFALookBehindUNode(L"", true)); return *end; default: raiseError(); return NULL; } } ++curInd; } noncap = 1; grc = --nonCapGroupCount; } if (noncap) cur = start = registerNode(new NFAGroupHeadUNode(grc)); else cur = start = registerNode(new NFASubStartUNode); } else cur = start = registerNode(new NFAGroupHeadUNode(grc)); } else cur = start = registerNode(new NFASubStartUNode); while (curInd < pattern.GetLength()) { wchar_t ch = pattern[curInd++]; next = NULL; if (error) return NULL; switch (ch) { case '^': if ((flags & WCPattern::MULTILINE_MATCHING) != 0) next = registerNode(new NFAStartOfLineUNode); else next = registerNode(new NFAStartOfInputUNode); break; case '$': if ((flags & WCPattern::MULTILINE_MATCHING) != 0) next = registerNode(new NFAEndOfLineUNode); else next = registerNode(new NFAEndOfInputUNode(0)); break; case '|': --groupCount; cur->next = registerNode(new NFAAcceptUNode); cur = start = registerNode(new NFAOrUNode(start, parse(inParen, 1))); break; case '\\': if (curInd < pattern.GetLength()) { bool eoi = 0; switch (pattern[curInd]) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': next = parseBackref(); break; case 'A': ++curInd; next = registerNode(new NFAStartOfInputUNode); break; case 'B': ++curInd; next = registerNode(new NFAWordBoundaryUNode(0)); break; case 'b': ++curInd; next = registerNode(new NFAWordBoundaryUNode(1)); break; case 'G': ++curInd; next = registerNode(new NFAEndOfMatchUNode); break; case 'Z': eoi = 1; case 'z': ++curInd; next = registerNode(new NFAEndOfInputUNode(eoi)); break; default: t = parseEscape(inv, quo); //printf("inv quo classes { %c %c %s }\n", inv ? 't' : 'f', quo ? 't' : 'f', t.c_str()); if (!quo) { if (t.GetLength() > 1 || inv) { if ((flags & WCPattern::CASE_INSENSITIVE) != 0) next = registerNode(new NFACIClassUNode(t, inv)); else next = registerNode(new NFAClassUNode(t, inv)); } else next = registerNode(new NFACharUNode(t[0])); } else next = parseQuote(); } } else raiseError(); break; case '[': if ((flags & WCPattern::CASE_INSENSITIVE) == 0) { NFAClassUNode * clazz = new NFAClassUNode(); CMString s = parseClass(); for (int i = 0; i < (int)s.GetLength(); ++i) clazz->vals[s[i]] = 1; next = registerNode(clazz); } else { NFACIClassUNode * clazz = new NFACIClassUNode(); CMString s = parseClass(); for (int i = 0; i < s.GetLength(); ++i) clazz->vals[to_lower(s[i])] = 1; next = registerNode(clazz); } break; case '.': { bool useN = 1, useR = 1; NFAClassUNode * clazz = new NFAClassUNode(1); if ((flags & WCPattern::UNIX_LINE_MODE) != 0) useR = 0; if ((flags & WCPattern::DOT_MATCHES_ALL) != 0) useN = useR = 0; if (useN) clazz->vals['\n'] = 1; if (useR) clazz->vals['\r'] = 1; next = registerNode(clazz); } break; case '(': { NFAUNode *end, *t1, *t2; t1 = parse(1, 0, &end); if (!t1) raiseError(); else if (t1->isGroupHeadNode() && (t2 = quantifyGroup(t1, end, grc)) != NULL) { cur->next = t2; cur = t2->next; } else { cur->next = t1; cur = end; } } break; case ')': if (!inParen) raiseError(); else if (inOr) { --curInd; cur = cur->next = registerNode(new NFAAcceptUNode); flags = oldFlags; return start; } else { if (ahead) { cur = cur->next = registerNode(new NFAAcceptUNode); flags = oldFlags; return *end = registerNode(new NFALookAheadUNode(start, pos)); } else if (indep) { cur = cur->next = registerNode(new NFAAcceptUNode); flags = oldFlags; return *end = registerNode(new NFAPossessiveQuantifierUNode(this, start, 1, 1)); } else { // capping or noncapping, it doesnt matter *end = cur = cur->next = registerNode(new NFAGroupTailUNode(grc)); next = quantifyGroup(start, *end, grc); if (next) { start = next; *end = next->next; } flags = oldFlags; return start; } } break; case '{': // registered pattern cur->next = parseRegisteredWCPattern(&next); if (cur->next) cur = next; break; case '*': case '+': case '?': // case '}': // case ']': raiseError(); break; default: if ((flags & WCPattern::CASE_INSENSITIVE) != 0) next = registerNode(new NFACICharUNode(ch)); else next = registerNode(new NFACharUNode(ch)); break; } if (next) cur = cur->next = quantify(next); } if (inParen) raiseError(); else { if (inOr) cur = cur->next = registerNode(new NFAAcceptUNode); if (end) *end = cur; } flags = oldFlags; if (error) return NULL; return start; }
CMString WCPattern::parseClass() { CMString t, ret; wchar_t ch, c1, c2; bool inv = 0, neg = 0, quo = 0; if (curInd < pattern.GetLength() && pattern[curInd] == '^') { ++curInd; neg = 1; } while (curInd < pattern.GetLength() && pattern[curInd] != ']') { ch = pattern[curInd++]; if (ch == '[') { t = parseClass(); ret = classUnion(ret, t); } else if (ch == '&' && curInd < pattern.GetLength() && pattern[curInd] == '&') { if (pattern[++curInd] != '[') { raiseError(); curInd = pattern.GetLength(); } else { ++curInd; t = parseClass(); ret = classIntersect(ret, t); } } else if (ch == '\\') { t = parseEscape(inv, quo); if (quo) { raiseError(); curInd = pattern.GetLength(); } else if (inv || t.GetLength() > 1) { // cant be part of a range (a-z) if (inv) t = classNegate(t); ret = classUnion(ret, t); } else if (curInd < pattern.GetLength() && pattern[curInd] == '-') { // part of a range (a-z) c1 = t[0]; ++curInd; if (curInd >= pattern.GetLength()) raiseError(); else { c2 = pattern[curInd++]; if (c2 == '\\') { t = parseEscape(inv, quo); if (quo) { raiseError(); curInd = pattern.GetLength(); } else if (inv || t.GetLength() > 1) raiseError(); else ret = classUnion(ret, classCreateRange(c1, c2)); } else if (c2 == '[' || c2 == ']' || c2 == '-' || c2 == '&') { raiseError(); curInd = pattern.GetLength(); } else ret = classUnion(ret, classCreateRange(c1, c2)); } } else ret = classUnion(ret, t); } else if (curInd < pattern.GetLength() && pattern[curInd] == '-') { c1 = ch; ++curInd; if (curInd >= pattern.GetLength()) raiseError(); else { c2 = pattern[curInd++]; if (c2 == '\\') { t = parseEscape(inv, quo); if (quo) { raiseError(); curInd = pattern.GetLength(); } else if (inv || t.GetLength() > 1) raiseError(); else ret = classUnion(ret, classCreateRange(c1, c2)); } else if (c2 == '[' || c2 == ']' || c2 == '-' || c2 == '&') { raiseError(); curInd = pattern.GetLength(); } else ret = classUnion(ret, classCreateRange(c1, c2)); } } else ret.AppendChar(ch); } if (curInd >= pattern.GetLength() || pattern[curInd] != ']') { raiseError(); ret = L""; } else { ++curInd; if (neg) ret = classNegate(ret); } return ret; }
bool ClassParser::parseHeader(const char *strHeader, const char *strHeaderFullFilePath) { unsigned int i; unsigned int iCount = strlen(strHeader); int iSquareBracketsOfClassIndex = 0; unsigned int iPosition; bool bIsParsed; EParseAction eAction = PARSE_ACTION_NOTHING; EParseActionSecondary eSecondaryAction = PARSE_ACTION_SECONDARY_NOTHING; for (i=0; i<iCount; i++) { switch (eAction) { case PARSE_ACTION_NOTHING: if (strncmp(strHeader+i, "/*", 2) == 0) { eAction = PARSE_ACTION_COMMENTS_OUT_MULTI_LINE; i++; if (ClassParserFind::findToNextChar(strHeader+i+1, "*/", &iPosition)) { i+=iPosition+2; eAction = PARSE_ACTION_NOTHING; } } else if (strncmp(strHeader+i, "//", 2) == 0) { eAction = PARSE_ACTION_COMMENTS_OUT_SINGLE_LINE; i++; if (ClassParserFind::findToNextChar(strHeader+i+1, "\n", &iPosition)) { i+=iPosition+1; eAction = PARSE_ACTION_NOTHING; } } else { if (eSecondaryAction != PARSE_ACTION_SECONDARY_NOTHING && eSecondaryAction != PARSE_ACTION_SECONDARY_IN_CLASS_BEGIN && eSecondaryAction != PARSE_ACTION_SECONDARY_IN_GOT_CLASS_NAME) { if (strHeader[i] == '{') { iSquareBracketsOfClassIndex++; } else if (strHeader[i] == '}') { iSquareBracketsOfClassIndex--; if (iSquareBracketsOfClassIndex == 0) { eSecondaryAction = PARSE_ACTION_SECONDARY_NOTHING; if (ClassParserFind::findToNextChar(strHeader+i, ";", &iPosition)) { i+=iPosition; } } } } switch (eSecondaryAction) { case PARSE_ACTION_SECONDARY_NOTHING: if (strncmp(strHeader+i, "class", 5) == 0) { ClassParserInformation s; s.m_strClassType = "class"; s.m_strFromHeaderFile = strHeaderFullFilePath; m_listClassInformation.append(s); i += 5; i += parseClass(strHeader+i, m_listClassInformation.size()-1); } else if (strncmp(strHeader+i, "struct", 6) == 0) { ClassParserInformation s; s.m_strClassType = "struct"; s.m_strFromHeaderFile = strHeaderFullFilePath; m_listClassInformation.append(s); i += 6; i += parseClass(strHeader+i, m_listClassInformation.size()-1); } else if (strncmp(strHeader+i, "enum", 4) == 0) { ClassParserInformation s; s.m_strClassType = "enum"; s.m_strFromHeaderFile = strHeaderFullFilePath; m_listClassInformation.append(s); i += 4; i += parseEnum(strHeader+i, m_listClassInformation.size()-1); } else if (strncmp(strHeader+i, "typedef", 7) == 0) { ClassParserInformation s; s.m_strClassType = "typedef"; s.m_strFromHeaderFile = strHeaderFullFilePath; m_listClassInformation.append(s); i += 7; i += parseTypedef(strHeader+i, m_listClassInformation.size()-1); } else if (strncmp(strHeader+i, "template", 8) == 0) { ClassParserInformation s; s.m_strClassType = "template"; s.m_strFromHeaderFile = strHeaderFullFilePath; i += 8; i += ClassParserFind::parseTemplate(strHeader+i, &s); m_listClassInformation.append(s); } else if (strncmp(strHeader+i, "union", 5) == 0) { ClassParserInformation s; s.m_strClassType = "union"; s.m_strFromHeaderFile = strHeaderFullFilePath; i += 5; i += ClassParserFind::parseTemplate(strHeader+i, &s); m_listClassInformation.append(s); } else if (strncmp(strHeader+i, "#define", 7) == 0) { i += 7; i += ClassParserFind::parseDefine(strHeader+i, this); } else if (strncmp(strHeader+i, "#include", 8) == 0) { bool bInPublicIncludeFolders; QString strInclude = ClassParserFind::getIncludeHeader(strHeader+i+8, &iPosition, &bInPublicIncludeFolders); if (strInclude.length() != 0) { i+=8+iPosition; ClassParserIncludeHeaderInformation s; s.m_bInPublicIncludeFolders = bInPublicIncludeFolders; s.m_strIncludeHeader = strInclude; s.m_strIncludeHeaderWithFullFilePath = findFullFilePathForHeaderInformation(&s, strHeaderFullFilePath); bIsParsed = isIncludeHeaderParsed(&s); m_listIncludeHeader.append(s); if (bIsParsed == false && s.m_strIncludeHeaderWithFullFilePath.length() != 0) { QByteArray ba = s.m_strIncludeHeaderWithFullFilePath.toLatin1(); parse(ba.data()); } } } else if (ClassParserFind::skipThisLine(strHeader, i, &iPosition) ) { i=iPosition; } else { i+= ClassParserFind::parsePossibleFunctionFromThisLine(strHeader+i); } break; default: break; } } break; case PARSE_ACTION_COMMENTS_OUT_MULTI_LINE: if (strncmp(strHeader+i, "*/", 2) == 0) { eAction = PARSE_ACTION_NOTHING; i++; } break; case PARSE_ACTION_COMMENTS_OUT_SINGLE_LINE: if (strncmp(strHeader+i, "\n", 1) == 0) { eAction = PARSE_ACTION_NOTHING; i++; } break; } } return false; }
unsigned int ClassParser::parseClass(const char *strHeader, int iClassIndex) { unsigned int i; unsigned int iCount = strlen(strHeader); unsigned int iPreviousImportantActionIndex = 0; int iSquareBracketsIndex = 0; int iSquareBracketsOfClassIndex = 0; int iBracketsIndex = 0; unsigned int iPosition; unsigned int iPositionAdd; int iMacroIndex; bool bInTheQuotes = false; EParseAction eAction = PARSE_ACTION_NOTHING; EParseActionSecondary eSecondaryAction = PARSE_ACTION_SECONDARY_IN_CLASS_BEGIN; EClassParserMemberType eFunctionType = FUNCTION_TYPE_PRIVATE; EClassParserMemberType eMemberType; for (i=0; i<iCount; i++) { switch (eAction) { case PARSE_ACTION_NOTHING: if (bInTheQuotes == false && strncmp(strHeader+i, "/*", 2) == 0) { eAction = PARSE_ACTION_COMMENTS_OUT_MULTI_LINE; i++; if (ClassParserFind::findToNextChar(strHeader+i+1, "*/", &iPosition)) { i+=iPosition+2; eAction = PARSE_ACTION_NOTHING; } } else if (bInTheQuotes == false && strncmp(strHeader+i, "//", 2) == 0) { eAction = PARSE_ACTION_COMMENTS_OUT_SINGLE_LINE; i++; if (ClassParserFind::findToNextChar(strHeader+i+1, "\n", &iPosition)) { i+=iPosition+1; eAction = PARSE_ACTION_NOTHING; } } else { if (eSecondaryAction != PARSE_ACTION_SECONDARY_NOTHING && eSecondaryAction != PARSE_ACTION_SECONDARY_IN_CLASS_BEGIN && eSecondaryAction != PARSE_ACTION_SECONDARY_IN_GOT_CLASS_NAME) { if (strHeader[i] == '{') { iSquareBracketsOfClassIndex++; } else if (strHeader[i] == '}') { iSquareBracketsOfClassIndex--; if (iSquareBracketsOfClassIndex == 0) { eSecondaryAction = PARSE_ACTION_SECONDARY_NOTHING; if (ClassParserFind::findToNextChar(strHeader+i, ";", &iPosition)) { i+=iPosition; return i; } } } } if (bInTheQuotes == false) { if (strHeader[i] == '\"') { bInTheQuotes = true; continue; } } else { if (i == 0 && strHeader[i] == '\"') { bInTheQuotes = false; continue; } else if (i != 0 && strHeader[i-1] != '\\' && strHeader[i] == '\"') { bInTheQuotes = false; continue; } } if (bInTheQuotes == false) { switch (eSecondaryAction) { case PARSE_ACTION_SECONDARY_NOTHING: break; case PARSE_ACTION_SECONDARY_IN_CLASS_BEGIN: eSecondaryAction = PARSE_ACTION_SECONDARY_IN_GOT_CLASS_NAME; iPreviousImportantActionIndex = i; i += ClassParserFind::parseClassName(strHeader+i, &m_listClassInformation[iClassIndex]); if (strHeader[i] == ';') { eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_NOTHING; return i; } else { if (strHeader[i] == '{') { eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_NOTHING; eFunctionType = FUNCTION_TYPE_PRIVATE; iSquareBracketsOfClassIndex++; } } break; case PARSE_ACTION_SECONDARY_IN_GOT_CLASS_NAME: if (strHeader[i] == '{') { eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_NOTHING; eFunctionType = FUNCTION_TYPE_PRIVATE; iSquareBracketsOfClassIndex++; } break; case PARSE_ACTION_SECONDARY_IN_THE_CLASS_NOTHING: case PARSE_ACTION_SECONDARY_IN_THE_CLASS_GETTING_FIRST_HAND_INFO: case PARSE_ACTION_SECONDARY_IN_THE_CLASS_GETTING_FUNCTION_BRACETS_OUT: if ( !ClassParserFind::isThisEqualToSpace(strHeader[i]) && iSquareBracketsIndex == 0 && iBracketsIndex == 0 && strHeader[i] != '(' && strHeader[i] != '{' && strHeader[i] != ';' && strHeader[i] != ')' && strHeader[i] != '}' && strHeader[i] != '=') { if (eSecondaryAction == PARSE_ACTION_SECONDARY_IN_THE_CLASS_GETTING_FUNCTION_BRACETS_OUT) { if (strncmp(strHeader+i, "const", 5) == 0) { i+=4; continue; } else if (iSquareBracketsIndex == 0 && iBracketsIndex == 0) { SClassParserPossibleMacroWithoutKnownledge s; s.m_pType = eFunctionType; s.m_strMacroLine = ClassParserFind::getStringBetween(strHeader, iPreviousImportantActionIndex, i) ; m_listClassInformation[iClassIndex].m_listPossibleMacroWithoutKnownledge.append( s ); } } eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_NOTHING; EClassParserClassMainType eClassType = ClassParserFind::isStartWithClassType(strHeader+i, &iPosition); if (eClassType == CLASS_MAIN_TYPE_CLASS) { ClassParserInformation s; s.m_strClassType = "class"; s.m_iParentClassIndex = iClassIndex; s.m_strFromHeaderFile = m_listClassInformation[iClassIndex].m_strFromHeaderFile; m_listClassInformation.append(s); i += iPosition; i += parseClass(strHeader+i, m_listClassInformation.size()-1); } else if (eClassType == CLASS_MAIN_TYPE_STRUCT) { ClassParserInformation s; s.m_strClassType = "struct"; s.m_iParentClassIndex = iClassIndex; s.m_strFromHeaderFile = m_listClassInformation[iClassIndex].m_strFromHeaderFile; m_listClassInformation.append(s); i += iPosition; i += parseClass(strHeader+i, m_listClassInformation.size()-1); } else if (eClassType == CLASS_MAIN_TYPE_ENUM) { ClassParserInformation s; s.m_strClassType = "enum"; s.m_iParentClassIndex = iClassIndex; s.m_strFromHeaderFile = m_listClassInformation[iClassIndex].m_strFromHeaderFile; m_listClassInformation.append(s); i += iPosition; i += parseEnum(strHeader+i, m_listClassInformation.size()-1); } else if (eClassType == CLASS_MAIN_TYPE_TYPEDEF) { ClassParserInformation s; s.m_strClassType = "typedef"; s.m_iParentClassIndex = iClassIndex; s.m_strFromHeaderFile = m_listClassInformation[iClassIndex].m_strFromHeaderFile; m_listClassInformation.append(s); i += iPosition; i += parseTypedef(strHeader+i, m_listClassInformation.size()-1); } else if (eClassType == CLASS_MAIN_TYPE_TEMPLATE) { ClassParserInformation s; s.m_strClassType = "template"; s.m_iParentClassIndex = iClassIndex; s.m_strFromHeaderFile = m_listClassInformation[iClassIndex].m_strFromHeaderFile; i += iPosition; i += ClassParserFind::parseTemplate(strHeader+i, &s); m_listClassInformation.append(s); } else if (eClassType == CLASS_MAIN_TYPE_UNION) { ClassParserInformation s; s.m_strClassType = "union"; s.m_iParentClassIndex = iClassIndex; s.m_strFromHeaderFile = m_listClassInformation[iClassIndex].m_strFromHeaderFile; i += iPosition; i += ClassParserFind::parseTemplate(strHeader+i, &s); m_listClassInformation.append(s); } else if (ClassParserFind::skipThisLine(strHeader, i, &iPosition) ) { i=iPosition; } else if (isStartWithMacroBeginForFunction(strHeader+i, &iMacroIndex)) { ClassParserFind::getFunctionWithMacroBegin(strHeader, i, eFunctionType, &m_listClassInformation[iClassIndex], &iPosition, m_listMacroBeginForMember[iMacroIndex]); i += iPosition; } else { eMemberType = ClassParserFind::isStartWithMemberType(strHeader+i, &iPosition); if (eMemberType != FUNCTION_TYPE_NONE) { i+=iPosition; eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_GETTING_FIRST_HAND_INFO; eFunctionType = eMemberType; } else { eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_GETTING_FUNCTION_OR_DATATYPE; iPreviousImportantActionIndex = i; } } } else if (eSecondaryAction == PARSE_ACTION_SECONDARY_IN_THE_CLASS_GETTING_FUNCTION_BRACETS_OUT) { if (strHeader[i] == '{' ) { iSquareBracketsIndex = 1; eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_GETTING_FUNCTION_INLINE; } else if (strHeader[i] == ';' ) { // This call creates function from // emit foo(); in inline function. // Also Q_OBJECT handled incorrectly. ClassParserFind::getFunctionBetween(strHeader, iPreviousImportantActionIndex, i, eFunctionType, &m_listClassInformation[iClassIndex], &iPositionAdd, ""); i+=iPositionAdd; eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_NOTHING; } else if (strHeader[i] == '=' && iBracketsIndex == 0 && iSquareBracketsIndex == 0) { ClassParserFind::getFunctionBetween(strHeader, iPreviousImportantActionIndex, i, eFunctionType, &m_listClassInformation[iClassIndex], &iPositionAdd, ""); i+=iPositionAdd; eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_NOTHING; } } break; case PARSE_ACTION_SECONDARY_IN_THE_CLASS_GETTING_FUNCTION_OR_DATATYPE: if (strHeader[i] == ';') { if (iSquareBracketsIndex == 0 && iBracketsIndex == 0) { ClassParserFind::getDataTypeBetween(strHeader, iPreviousImportantActionIndex, i, eFunctionType, &m_listClassInformation[iClassIndex]); } else { ClassParserFind::getFunctionBetween(strHeader, iPreviousImportantActionIndex, i, eFunctionType, &m_listClassInformation[iClassIndex], &iPositionAdd, ""); i+=iPositionAdd; } eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_NOTHING; } else if (strHeader[i] == '(' ) { iBracketsIndex++; eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_GETTING_FUNCTION_BRACETS_IN; } break; case PARSE_ACTION_SECONDARY_IN_THE_CLASS_GETTING_FUNCTION_BRACETS_IN: if (strHeader[i] == ';' ) { ClassParserFind::getFunctionBetween(strHeader, iPreviousImportantActionIndex, i, eFunctionType, &m_listClassInformation[iClassIndex], &iPositionAdd, ""); i+=iPositionAdd; eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_NOTHING; } else if (strHeader[i] == '(' ) { iBracketsIndex++; } else if (strHeader[i] == ')' ) { iBracketsIndex--; if (iBracketsIndex == 0) { char c = ClassParserFind::findToNextNextValidNonSpaceChar(strHeader+i+1, &iPosition); if (c == '(') { // function? still continues i += iPosition; iBracketsIndex++; } else { eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_GETTING_FUNCTION_BRACETS_OUT; } } } else if (strHeader[i] == '=' && iBracketsIndex == 0 && iSquareBracketsIndex == 0) { ClassParserFind::getFunctionBetween(strHeader, iPreviousImportantActionIndex, i, eFunctionType, &m_listClassInformation[iClassIndex], &iPositionAdd, ""); i+=iPositionAdd; eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_NOTHING; } break; case PARSE_ACTION_SECONDARY_IN_THE_CLASS_GETTING_FUNCTION_INLINE: if (strHeader[i] == '{' ) { iSquareBracketsIndex++; } else if (strHeader[i] == '}' ) { iSquareBracketsIndex--; if (iSquareBracketsIndex==0) { ClassParserFind::getFunctionBetween(strHeader, iPreviousImportantActionIndex, i, eFunctionType, &m_listClassInformation[iClassIndex], &iPositionAdd, ""); i+=iPositionAdd; eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_NOTHING; } } else if (strHeader[i] == ';' ) { if (iSquareBracketsIndex==0) { ClassParserFind::getFunctionBetween(strHeader, iPreviousImportantActionIndex, i, eFunctionType, &m_listClassInformation[iClassIndex], &iPositionAdd, ""); i+=iPositionAdd; eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_NOTHING; } } else if (strHeader[i] == '=') { if (iSquareBracketsIndex == 0) { ClassParserFind::getFunctionBetween(strHeader, iPreviousImportantActionIndex, i, eFunctionType, &m_listClassInformation[iClassIndex], &iPositionAdd, ""); i+=iPositionAdd; eSecondaryAction = PARSE_ACTION_SECONDARY_IN_THE_CLASS_NOTHING; } } break; } } } break; case PARSE_ACTION_COMMENTS_OUT_MULTI_LINE: if (strncmp(strHeader+i, "*/", 2) == 0) { eAction = PARSE_ACTION_NOTHING; i++; } break; case PARSE_ACTION_COMMENTS_OUT_SINGLE_LINE: if (strncmp(strHeader+i, "\n", 1) == 0) { eAction = PARSE_ACTION_NOTHING; i++; } break; } } return i; }
void PackageParser::parse() { while (stream_.hasMoreTokens()) { auto documentation = parseDocumentationToken(); auto exported = Attribute<E_EARTH_GLOBE_EUROPE_AFRICA>().parse(&stream_); auto theToken = stream_.consumeToken(IDENTIFIER); switch (theToken.value[0]) { case E_PACKAGE: { exported.disallow(); auto nameToken = stream_.consumeToken(VARIABLE); auto namespaceToken = stream_.consumeToken(IDENTIFIER); auto name = nameToken.value.utf8CString(); package_->loadPackage(name, namespaceToken.value[0], theToken); continue; } case E_CROCODILE: parseProtocol(documentation, theToken, exported.set()); continue; case E_TURKEY: parseEnum(documentation, exported.set()); continue; case E_RADIO: exported.disallow(); package_->setRequiresBinary(); if (strcmp(package_->name(), "_") == 0) { throw CompilerErrorException(theToken, "You may not set 📻 for the _ package."); } continue; case E_CRYSTAL_BALL: { exported.disallow(); if (package_->validVersion()) { throw CompilerErrorException(theToken, "Package version already declared."); } auto major = stream_.consumeToken(INTEGER).value.utf8CString(); auto minor = stream_.consumeToken(INTEGER).value.utf8CString(); uint16_t majori = strtol(major, nullptr, 0); uint16_t minori = strtol(minor, nullptr, 0); delete [] major; delete [] minor; package_->setPackageVersion(PackageVersion(majori, minori)); if (!package_->validVersion()) { throw CompilerErrorException(theToken, "The provided package version is not valid."); } continue; } case E_WALE: { exported.disallow(); EmojicodeChar className, enamespace; bool optional; auto &classNameToken = parseTypeName(&className, &enamespace, &optional); if (optional) { throw CompilerErrorException(classNameToken, "Optional types are not extendable."); } Type type = typeNothingness; if (!package_->fetchRawType(className, enamespace, optional, theToken, &type)) { throw CompilerErrorException(classNameToken, "Class does not exist."); } if (type.type() != TT_CLASS) { throw CompilerErrorException(classNameToken, "Only classes are extendable."); } // Native extensions are allowed if the class was defined in this package. parseClassBody(type.eclass, nullptr, type.eclass->package() == package_); continue; } case E_RABBIT: parseClass(documentation, theToken, exported.set()); continue; case E_SCROLL: { exported.disallow(); auto pathString = stream_.consumeToken(STRING); auto relativePath = pathString.position().file; auto fileString = pathString.value.utf8CString(); char *str = fileString; const char *lastSlash = strrchr(relativePath, '/'); if (lastSlash != nullptr) { const char *directory = strndup(relativePath, lastSlash - relativePath); asprintf(&str, "%s/%s", directory, fileString); delete [] fileString; delete [] directory; } PackageParser(package_, lex(str)).parse(); delete [] str; continue; } default: ecCharToCharStack(theToken.value[0], f); throw CompilerErrorException(theToken, "Unexpected identifier %s", f); break; } } }