/* static */ bool cCharUtil::PopNextChar( TSTRING::const_iterator& cur, const TSTRING::const_iterator& end, TSTRING::const_iterator& first, TSTRING::const_iterator& last ) { bool f = PeekNextChar( cur, end, first, last ); cur = last; // pop causes 'cur' to move to just beyond character ('last') return f; }
bool JSONScanner::IsJSONNumber() { bool firstDigitIsAZero = false; if (PeekNextChar() == '0') { firstDigitIsAZero = true; currentChar++; } //partial verification of number JSON grammar. while (currentChar < inputText + inputLen) { switch(ReadNextChar()) { case 0: return false; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (firstDigitIsAZero) { return false; } break; case '.': { // at least one digit after '.' if(currentChar < inputText + inputLen) { char16 nch = ReadNextChar(); if('0' <= nch && nch <= '9') { return true; } else { return false; } } else { return false; } } //case 'E': //case 'e': // return true; default: return true; } firstDigitIsAZero = false; } return true; }
/* ** Tokens are separated by a space or quote: ** Ex1: "ABC=WXX /BN""X"/CL --> 2 token (inside the quote, the "" is equivalent to \") ** 1) "ABC=WXX /BN""X" ** 2) /CL ** Ex2: MAKE IT --> ** 1) MAKE ** 2) IT */ LISTCHAR* MakeListTokens(char* zsText, int* pError) { char buff[8]; char strToken[512]; char stack[256]; LISTCHAR* pListToken = NULL; char tchszCur = '0'; char* pch = zsText; strToken[0] = '\0'; memset (stack, '\0', sizeof (stack)); while (*pch != '\0') { tchszCur = *pch; if (stack[0]) /* We're inside the quote (single or double) */ { char tchTop = stack_top(stack); if (tchTop == tchszCur) /* The current character is a quote (single or double) */ { if (PeekNextChar(pch) != tchTop) /* The next char is not a quote. (Here we found the end quote) */ { stack_PopState(stack); STprintf(buff, "%c", tchszCur); STcat (strToken, buff); } else { /* ** We consider the current quote the escaped of the next quote (consecutive quotes): */ STprintf(buff, "%c", tchszCur); STcat (strToken, buff); STprintf(buff, "%c", PeekNextChar(pch)); STcat (strToken, buff); CMnext(pch); } } else { STprintf(buff, "%c", tchszCur); STcat (strToken, buff); } CMnext(pch); continue; } /* ** We found a space (token separator): */ if (tchszCur == ' ' || tchszCur == '='/* || tchszCur == cSep(!strTokenSeparator.IsEmpty() && strTokenSeparator.Find(tchszCur) != -1)*/) { if (strToken[0]) { pListToken = AddToken(pListToken, strToken); strToken[0] = '\0'; } if (tchszCur == '=') { pListToken = AddToken(pListToken, "="); } } else { if (tchszCur == '\"' || tchszCur == '\'') /* Found the begin quote.*/ { /* ** Note: the begin quote cannote be an escape of quote because ** the quote can be escaped only if it is inside the quote: */ stack_PushState (stack, tchszCur); } STprintf(buff, "%c", tchszCur); STcat (strToken, buff); } CMnext(pch); if (*pch == '\0') { if (strToken[0]) { pListToken = AddToken(pListToken, strToken); strToken[0] = '\0'; } } } if (strToken[0]) { pListToken = AddToken(pListToken, strToken); strToken[0] = '\0'; } if (stack[0]) { pListToken = ListChar_Done(pListToken); if (pError) *pError = 1; } if (pError) *pError = 0; return pListToken; }
void Tokenizer::SkipSpaces() { while (Good() && IsWhitespace(PeekNextChar())) { GetNextChar(); } }
void Tokenizer::ReadToken(Token& token) { start: SkipSpaces(); token.value_s.clear(); if (!Good()) { token.type = Token::type_eof; token.pos_string = "EOF"; return; } std::stringstream token_tmp; if (!include_stack.empty() && !include_stack.back().name.empty()) token_tmp << include_stack.back().name << " , "; token_tmp << "line " << include_stack.back().line << " , column " << include_stack.back().column; token.pos_string = token_tmp.str(); char c = GetNextChar(); token.value_s += c; // first find what token is it, and handle all except numbers switch (c) { case '[': { token.type = Token::type_section_name; token.value_s.clear(); bool skip_next_eol_char = false; while (Good()) { c = GetNextChar(); // std::string has problem with zero characters, replace by space. if (c == 0) { c = ' '; } if (c == '\\') { if (Good()) { token.value_s += GetNextChar(); } else { ReportError(token, "Quotes not closed before end of file"); return; } } else if (c == ']') { return; } else { token.value_s += c; } // handle end of line if (skip_next_eol_char) { skip_next_eol_char = false; } else if (c == 10 || c == 13) { //++line; //column=1; if ((PeekNextChar() == 10 || PeekNextChar() == 13) && (PeekNextChar() != c)) skip_next_eol_char = true; } } ReportError(token, "Quotes not closed before end of file"); return; } case '{': token.type = Token::type_enter_section; return; case '}': token.type = Token::type_leave_section; return; case ';': token.type = Token::type_semicolon; return; case '=': token.type = Token::type_entry_value; token.value_s = ""; while (Good() && PeekNextChar() != ';') { unsigned char c_ = GetNextChar(); token.value_s += c_; } return; case '/': // handle comments if (PeekNextChar() == '/') { //SkipToEOL(); if (!include_stack.empty()) { std::string tmp; std::getline((*include_stack.back().stream), tmp); include_stack.back().line += 1; include_stack.back().column = 1; } goto start; } else if (PeekNextChar() == '*') { // multi-line comment while (Good()) { char c1 = GetNextChar(); if ((c1 == '*') && (PeekNextChar() == '/')) { GetNextChar(); break; } } goto start; } default: while (Good() && PeekNextChar() != '=') { unsigned char c_ = GetNextChar(); token.value_s += c_; } token.type = Token::type_entry_name; return; } }
FarXMLNode *FarXMLScanner::ParseChildNode() { SkipWhitespace(); int tagStartLine = fCurLine; int tagStartCol = GetCurColumn(); if (!NextExpectedChar ('<')) return NULL; FarString tagName = NextName(); if (tagName.IsEmpty()) return NULL; FarXMLNode *theNode = new FarXMLNode(); theNode->SetTag (tagName); theNode->SetStartPosition (tagStartLine, tagStartCol); while (1) { SkipWhitespace(); char c = PeekNextChar(); if (c == '/') { NextChar(); if (!NextExpectedChar ('>')) { delete theNode; return NULL; } break; } else if (c == '>') { NextChar(); SkipWhitespace(); while (1) { if (PeekNextChar() == '<' && PeekNextChar (1) == '/') break; FarXMLNode *nextChild = ParseChildNode(); if (!nextChild) { delete theNode; return NULL; } theNode->AddChild (nextChild); SkipWhitespace(); } NextChar(); // < NextChar(); // / FarString closeTagName = NextName(); if (closeTagName != tagName) { ReportError (tagName); delete theNode; return NULL; } SkipWhitespace(); if (!NextExpectedChar ('>')) { delete theNode; return NULL; } break; } else { if (!ParseAttribute (theNode)) { delete theNode; return NULL; } } } theNode->SetEndPosition (fCurLine, GetCurColumn()); SkipWhitespace(); return theNode; }