/* Parse a class declaration. The current token is the 'class' keyword. class:= CLASSIDENT ';' // Forward declaration | CLASSIDENT ':' PARENTCLASSIDENT CLASSBODY // Subclass (not used yet!) | CLASSIDENT CLASSBODY */ void parseClass(GTokenType token) { PPARSEINFO pParseInfo=(PPARSEINFO)gScanner->user_data; pParseInfo->pCurInterface=createInterfaceStruct(); /* Get the class name. */ pParseInfo->pCurInterface->chrName=parseClassIdent(); /* Check for forward declaration */ if(matchNext(';')) { doForwardClassDeclaration(); } else { /* This is the real thing. */ doClassDeclaration(); }/* not forward declaration */ #if 0 g_printf("\n\n"); /* In printdata.c */ printAllInterfaces(); g_printf("\n\n"); printInterface(pParseInfo->pCurInterface); #endif }
bool ixion::regex<T>::backref_matcher::match(backref_stack &brstack,T const &candidate,TIndex at) { T matchstr = brstack.get(Backref,candidate); this->MatchLength = matchstr.size(); if (at+matchstr.size() > candidate.size()) return false; return (T(candidate.begin()+at,candidate.begin()+at+matchstr.size()) == matchstr) && matchNext(brstack,candidate,at+matchstr.size()); }
void parseMetaClass(void) { GTokenValue value; if(!matchNext('=')) { getNextToken(); /* Make sure error references the correct token */ g_scanner_unexp_token(gScanner, ';', NULL, NULL, NULL, "Error in metaclass definition.", TRUE); /* is_error */ exit(1); } /* Get the identifier */ if(!matchNext(G_TOKEN_IDENTIFIER)) { g_scanner_unexp_token(gScanner, G_TOKEN_IDENTIFIER, NULL, NULL, NULL, "Class name is not a valid identifier.", TRUE); /* is_error */ exit(1); } value=gScanner->value; pParseInfo->pCurInterface->chrMetaClass=g_strdup(value.v_identifier); if(!matchNext(';')) { getNextToken(); /* Make sure error references the correct token */ g_scanner_unexp_token(gScanner, ';', NULL, NULL, NULL, "Error in metaclass definition.", TRUE); /* is_error */ exit(1); } }
/* Current token is CLASSIDENT. CLASSBODY:= '{' CBODY | '{' CBODY ';' */ static void parseClassBody(void) { exitIfNotMatchNext('{', "No opening brace for class body."); parseCBody(); /* Remove a terminating ';' from the input if present. */ matchNext(';'); }
bool ixion::regex<T>::backref_close_matcher::match( backref_stack &brstack,T const &candidate,TIndex at) { typename backref_stack::rewind_info ri = brstack.getRewindInfo(); brstack.close(at); bool result = matchNext(brstack,candidate,at); if (!result) brstack.rewind(ri); return result; }
static void doClassDeclaration(void) { PPARSEINFO pParseInfo=(PPARSEINFO)gScanner->user_data; PINTERFACE pif; gchar *chrTemp=pParseInfo->pCurInterface->chrName; /* Check if we already have a (maybe forward) declaration */ pif=findInterfaceFromName(pParseInfo->pCurInterface->chrName); if(pif) { if(pif->fIsForwardDeclaration) { /* Remove the forward declaration and insert the real thing afterwards. */ deRegisterInterface(pif); } else { /* It˚s the declaration from the *.h file. Save a pointer to this information. */ pParseInfo->pClassDefinition=pif; deRegisterInterface(pif); } } pParseInfo->pCurInterface->chrName=chrTemp; pParseInfo->pCurInterface->chrSourceFileName=g_strdup(pParseInfo->chrCurrentSourceFile); /* It's save to register the interface right here even if the struct is almost empty. If anything goes wrong later we will exit anyway. */ registerInterface(); /* The class definition in *.nom files does not contain all the stuff an interface may define. We use the found interface to fill the gaps. If we don˚t have an interface something went wrong and we quit. */ if(!pParseInfo->pClassDefinition) { g_message("Line %d: Error during class parsing. No class definition found. MAke sure you included the *.ih file.", g_scanner_cur_line(gScanner)); cleanupAndExit(0); } pParseInfo->pCurInterface->chrParent=g_strdup(pParseInfo->pClassDefinition->chrParent); /* Note: We don˚t support subclasses yet. */ if(matchNext(':')) { parseParentClassIdent(); } parseClassBody(); }
static bool acceptVariadic(size_t variadicLength, const SVariadicWordDefinition* variadicWord, bool lineStart) { lex_Current.length = variadicLength; if (variadicWord->callback && !variadicWord->callback(lex_Current.length)) { return matchNext(lineStart); } if (variadicWord->token == T_ID && lineStart) { skip(lex_Current.length); lex_Current.token = T_LABEL; return true; } else { skip(lex_Current.length); lex_Current.token = variadicWord->token; return true; } }
static bool stateNormal() { bool lineStart = g_currentBuffer->atLineStart; g_currentBuffer->atLineStart = false; for (;;) { if (matchNext(lineStart)) { return true; } else { if (fstk_ProcessNextBuffer()) { lineStart = g_currentBuffer->atLineStart; g_currentBuffer->atLineStart = false; } else { lex_Current.token = T_NONE; return false; } } } }
/* Parse the class name. If we already encountered this class the name is registered as a symbol. IF this is the first time the name is an identifier. Note that the current token is the 'class' keyword. CLASSIDENT:= G_TOKEN_IDENTIFIER | IDL_SYMBOL_INTERFACE */ static gchar* parseClassIdent(void) { PPARSEINFO pParseInfo=(PPARSEINFO)gScanner->user_data; if(matchNext(G_TOKEN_IDENTIFIER)) { /* Save interface info */ GTokenValue value=gScanner->value; return g_strdup(value.v_identifier); } else { PSYMBOL pCurSymbol; GTokenValue value; /* If the interface name is a symbol, it means the interface was already registered before. Maybe because of a forward statement. We will check that in the function which called us. */ exitIfNotMatchNext(G_TOKEN_SYMBOL, "Keyword 'class' must be followed by an identifier"); /* Check if it's one of our interface symbols */ value=gScanner->value; pCurSymbol=value.v_symbol; if(IDL_SYMBOL_REGINTERFACE!=pCurSymbol->uiSymbolToken) { /* No, some other symbol */ g_scanner_unexp_token(gScanner, G_TOKEN_SYMBOL, NULL, NULL, NULL, "Keyword 'class' is not followed by a valid identifier.", TRUE); /* is_error */ cleanupAndExit(1); } /* Save interface name */ return g_strdup(pCurSymbol->chrSymbolName); } }
/* Parse a typespec e.g. 'gulong' or 'gulong*'. Current token is the typespec. TS:= TYPE_SPEC | TYPE_SPEC TYPE_SPEC // This is for something like 'unsigned long' | TYPE_SPEC '*' | TYPE_SPEC TYPE_SPEC '*' // This is for something like 'unsigned long*' */ void parseTypeSpec(PMETHODPARAM pMethodParam) { char *chrTemp; /* Return type part 1 */ chrTemp=getTypeSpecStringFromCurToken(); /* A second typespec part (e.g. 'unsigned long')? */ if(matchNextKind(KIND_TYPESPEC)) { char *chrTemp2=getTypeSpecStringFromCurToken(); pMethodParam->chrType=g_strconcat(chrTemp, " ", chrTemp2 ,NULL); g_free(chrTemp2); g_free(chrTemp); } else{ /* Return type */ pMethodParam->chrType=chrTemp; } /* Do we return a pointer (check for '*') */ while(matchNext('*')) pMethodParam->uiStar++; }
bool ixion::regex<T>::alternative_matcher::connector::match(backref_stack &brstack,T const &candidate,TIndex at) { return matchNext(brstack,candidate,at); }
bool ixion::regex<T>::end_matcher::match(backref_stack &brstack,T const &candidate,TIndex at) { return (at == candidate.size()) && matchNext(brstack,candidate,at); }
bool ixion::regex<T>::sequence_matcher::match(backref_stack &brstack,T const &candidate,TIndex at) { if (at+MatchStr.size() > candidate.size()) return false; return (T(candidate.begin()+at,candidate.begin()+at+MatchStr.size()) == MatchStr) && matchNext(brstack,candidate,at+MatchStr.size()); }
bool ixion::regex<T>::quantifier::match(backref_stack &brstack,T const &candidate,TIndex at) { // this routine does speculative matching, so it must pay close attention // to rewind the backref stack appropriately. // NB: matchNext does the rewinding automatically, whereas speculative // matches of the quantified portion must be rewound. // There should be at least one character in each match, we'd // run to Baghdad otherwise. if (!Quantified) return matchNext(brstack,candidate,at); // calculate accurate maximum match count TSize quant_min = Quantified->minimumSubsequentMatchLength(); if (quant_min == 0) quant_min = 1; TSize max_count = candidate.size() - at; if (this->Next) max_count -= this->Next->minimumSubsequentMatchLength(); max_count = max_count/quant_min + 1; if (MaxValid) max_count = NUM_MIN(max_count,MaxCount); // check that at least MinCount matches take place (non-speculative) TIndex idx = at; for (TSize c = 1;c <= MinCount;c++) if (Quantified->match(brstack,candidate,idx)) idx += Quantified->subsequentMatchLength(); else return false; // determine number of remaining matches TSize remcount = max_count-MinCount; // test for the remaining matches in a way that depends on Greedy flag if (Greedy) { // try to gobble up as many matches of quantified part as possible // (speculative) std::stack<backtrack_stack_entry> successful_indices; { backtrack_stack_entry entry = { idx,brstack.getRewindInfo() }; successful_indices.push(entry); } while (Quantified->match(brstack,candidate,idx) && successful_indices.size()-1 < remcount) { idx += Quantified->subsequentMatchLength(); backtrack_stack_entry entry = { idx,brstack.getRewindInfo() }; successful_indices.push(entry); } // backtrack until rest of sequence also matches while (successful_indices.size() && !matchNext(brstack,candidate,successful_indices.top().Index)) { brstack.rewind(successful_indices.top().RewindInfo); successful_indices.pop(); } if (successful_indices.size()) { this->MatchLength = successful_indices.top().Index - at; return true; } else return false; } else { for (TSize c = 0;c <= remcount;c++) { if (matchNext(brstack,candidate,idx)) { this->MatchLength = idx-at; return true; } // following part runs once too much, effectively: // if c == remcount, idx may be increased, but the search fails anyway // => no problem if (Quantified->match(brstack,candidate,idx)) idx += Quantified->subsequentMatchLength(); else return false; } return false; } }
/* Parse the class version. Note that the identifier is the current symbol.. CV:= IDL_SYMBOL_CLSVERSION '(' NUM ',' NUM ')' ';' */ void parseClassVersion(void) { GTokenValue value; if(!matchNext('(')) { getNextToken(); /* Make sure error references the correct token */ g_scanner_unexp_token(gScanner, '(', NULL, NULL, NULL, "Error in NOMCLASSVERSION()", TRUE); /* is_error */ exit(1); } if(!matchNext(G_TOKEN_INT)) { getNextToken(); /* Make sure error references the correct token */ g_scanner_unexp_token(gScanner, G_TOKEN_INT, NULL, NULL, NULL, "Error in NOMCLASSVERSION()", TRUE); /* is_error */ exit(1); } value=gScanner->value; pParseInfo->pCurInterface->ulMajor=value.v_int; if(!matchNext(',')) { getNextToken(); /* Make sure error references the correct token */ g_scanner_unexp_token(gScanner, ',', NULL, NULL, NULL, "Error in NOMCLASSVERSION()", TRUE); /* is_error */ exit(1); } if(!matchNext(G_TOKEN_INT)) { getNextToken(); /* Make sure error references the correct token */ g_scanner_unexp_token(gScanner, G_TOKEN_INT, NULL, NULL, NULL, "Error in NOMCLASSVERSION()", TRUE); /* is_error */ exit(1); } value=gScanner->value; pParseInfo->pCurInterface->ulMinor=value.v_int; if(!matchNext(')')) { getNextToken(); /* Make sure error references the correct token */ g_scanner_unexp_token(gScanner, ')', NULL, NULL, NULL, "Error in NOMCLASSVERSION()", TRUE); /* is_error */ exit(1); } if(!matchNext(';')) { getNextToken(); /* Make sure error references the correct token */ g_scanner_unexp_token(gScanner, ';', NULL, NULL, NULL, "Error in NOMCLASSVERSION()", TRUE); /* is_error */ exit(1); } }
int KReg::matchNext(const char *str, int str_len, int flag, int *workspace, int wscount) { int ovector[DEFAULT_OVECTOR]; return matchNext(str, str_len, flag, ovector, DEFAULT_OVECTOR, workspace, wscount); }