std::string BinaryInput::readStringNewline() { int64 n = 0; if ((m_pos + m_alreadyRead + n) < (m_length - 1)) { prepareToRead(1); } if ( ((m_pos + m_alreadyRead + n) < (m_length - 1)) && ! isNewline(m_buffer[m_pos + n])) { ++n; while ( ((m_pos + m_alreadyRead + n) < (m_length - 1)) && ! isNewline(m_buffer[m_pos + n])) { prepareToRead(1); ++n; } } const std::string s = readString(n); // Consume the newline char firstNLChar = readUInt8(); // Consume the 2nd newline if (isNewline(m_buffer[m_pos + 1]) && (m_buffer[m_pos + 1] != firstNLChar)) { readUInt8(); } return s; }
void DefaultLexer::readLineComment() { skipChar(); // skip '/' skipChar(); // skip '/' char c = lookChar(); while (c && !isNewline(c)) { skipChar(); c = lookChar(); } if (isNewline(c)) readNewline(c); }
/** * @brief Generates a string. * * Will seek until the @p endMarker is found, any '\' escapes * the marker. The resulting string is stored in @p arg. * * At the end of this function, the parser cursor is just after the closing * marker. * * @return true if an error occurred, false otherwise. */ bool NepParser::helpGenString(std::string& arg, char endMarker) { size_t start = getCurPos(); size_t stLine=getCurLine(), stCol=getCurCol(); while( notEof() ) { char ch = getCurRaw(); if( ch == endMarker ) { arg += getSubString(start, getCurPos()); iterCur(); return false; } else if( ch == '\\') { arg += getSubString(start, getCurPos()); iterCur(); start = getCurPos(); } else if( isNewline(ch) ) break; iterCur(); } mScript.addError(Nepeta::ErrNoCloseString, "", stLine, stCol, getCurLine(), getCurCol()); return true; }
Token *Lexer::nextToken() { while(true) { switch(_currentChar.toAscii()) { case '\'': return scanCharacter(); case '"': return scanText(); case '(': return scan(Token::LeftParenthesis); case ')': return scan(Token::RightParenthesis); case '[': return scan(Token::LeftBracket); case ']': return scanRightBracket(); case '{': return scan(Token::LeftBrace); case '}': return scan(Token::RightBrace); case ';': return scan(Token::Semicolon); default: if(isEof()) return scan(Token::Eof); else if(isLineComment()) consumeLineComment(); else if(isBlockComment()) consumeBlockComment(); else if(isNewline()) return scanNewline(); else if(isSpace()) consumeSpaces(); else if(isName()) return scanName(); else if(isBackquotedName()) return scanBackquotedName(); else if(isNumber()) return scanNumber(); else if(isOperator()) return scanOperator(); else throw lexerException(QString("invalid character: '%1'").arg(_currentChar)); } } }
/** * @brief Parses in the argument context for the given node. */ void NepParser::genCtxArg(Nepeta::Node &data) { while( notEof() ) { char ch = getCurRaw(); if( isSpace(ch) ) { iterCur(); } else if( checkIdentifier(ch) ) { genArgWord(data); } else if( checkString(ch) ) { genArgString(data); } else if( checkBlock(ch) ) { genArgBlock(data); } else if( isNewline(ch) || ch == ';' ) { iterCur(); return; } else if( ch == '\\' ) { iterCur(); helpSeekNewline(true); } else if( ch == '&' ) { genArgReference(data); } else { mScript.addError(Nepeta::ErrIllegalCharacter, std::string(1,ch), getCurLine(), getCurCol()); helpSeekNewline(false); break; } } }
///////////////////////////////////// // // Strings // Token *parseString( Tokenizer *tokenizer ) { StatefulString *ss = tokenizer->ss_; assert( isStringStart( ss, 0 ) ); int start, length; StatefulStringPosition pos1, pos2; wchar_t temp; Token *token; length = 0; pos1 = ss->next_position; wchar_t quote = ss_getchar( ss ); start = ss->next_index; // Exclude the quotes while ( ( temp = ss_getchar( ss ) ) != WEOF && !isNewline( temp ) && temp != quote ) { length++; if ( temp == L'\\' ) { ss_getchar( ss ); length++; } } pos2 = ss->next_position; token = token_new( ss_substr( ss, start, length ), length, STRING, pos1, pos2 ); wchar_t *error = malloc( 201 * sizeof( wchar_t ) ); error[ 0 ] = L'\0'; if ( temp == WEOF ) { swprintf( error, 200, L"Encountered end-of-file while parsing a string. Looks like a `%C` is missing.", quote ); } else if ( isNewline( temp ) ) { error = L"Encountered a newline while parsing a string. Strings can only contain newlines if they're properly escaped (e.g. `\\[\\n]`)"; } if ( wcscmp( error, L"" ) != 0 ) { tokenizer_error( tokenizer, error, token ); } else { free( error ); } return token; }
/** * @brief Iterates the parser position one forward. * * The line and column counter is updated as well. */ void NepParser::iterCur() { // Skip the newline if(getCurRaw() == '\n' || getCurRaw() == '\r') { if(isNewline(getNext())) mCur++; mCol=0; mLine++; } mCol++; mCur++; }
/** * @brief Skips a comment block. * * Will, depending on if a single or multi-line comment was found, iterate * through the respective comment type. If this is not a real comment, * notify the error and return. * * The function assumes the parser is at a comment start marker '/'. It * ends where the parser cursor is after the closing comment (for * single-line comments this is at the newline, and for multi-line this is * at the character just after the closing '/'). */ bool NepParser::helpSkipComment() { size_t stLine = getCurLine(), stCol = getCurCol(); iterCur(); // Get identifier char ch = getCur(); if(!(ch=='*' || ch=='/')) { mScript.addError( Nepeta::ErrIllegalCharacter, std::string(1,ch), getCurLine(),getCurCol()); helpSeekNewline(false); return false; } bool isMultiline = (ch == '*'); iterCur(); bool didFinish = false; while(notEof()) { iterCur(); ch = getCur(); // Multiline: // If the closing marker detected, check the next character and iterate // to it if closing. if(isMultiline) { if(ch == '*' && getNext() == '/') { iterCur(); didFinish = true; break; } } // Singleline: // Break on end-of-line else if(isNewline(ch)) break; } if(isMultiline && !didFinish) { mScript.addError( Nepeta::ErrCommentNotClosed, "", stLine,stCol); } else didFinish = true; if(isMultiline) iterCur(); return didFinish; }
void PUScriptLexer::setToken(const std::string &lexeme, int line, const std::string &source, PUScriptTokenList *tokens) { const char openBracket = '{', closeBracket = '}', colon = ':', quote = '\"', var = '$'; PUScriptToken* token = new (std::nothrow) PUScriptToken; token->lexeme = lexeme; token->line = line; token->file = source; bool ignore = false; // Check the user token map first if(lexeme.size() == 1 && isNewline(lexeme[0])) { token->type = TID_NEWLINE; if(!tokens->empty() && tokens->back()->type == TID_NEWLINE){ ignore = true; delete token; } } else if(lexeme.size() == 1 && lexeme[0] == openBracket) token->type = TID_LBRACKET; else if(lexeme.size() == 1 && lexeme[0] == closeBracket) token->type = TID_RBRACKET; else if(lexeme.size() == 1 && lexeme[0] == colon) token->type = TID_COLON; else if(lexeme[0] == var) token->type = TID_VARIABLE; else { // This is either a non-zero length phrase or quoted phrase if(lexeme.size() >= 2 && lexeme[0] == quote && lexeme[lexeme.size() - 1] == quote) { token->type = TID_QUOTE; } else { token->type = TID_WORD; } } if(!ignore) tokens->push_back(token); }
void ScriptLexer::setToken(const Ogre::String &lexeme, Ogre::uint32 line, const String &source, Ogre::ScriptTokenList *tokens) { #if OGRE_WCHAR_T_STRINGS const wchar_t openBracket = L'{', closeBracket = L'}', colon = L':', quote = L'\"', var = L'$'; #else const char openBracket = '{', closeBracket = '}', colon = ':', quote = '\"', var = '$'; #endif ScriptTokenPtr token(OGRE_NEW_T(ScriptToken, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); token->lexeme = lexeme; token->line = line; token->file = source; bool ignore = false; // Check the user token map first if(lexeme.size() == 1 && isNewline(lexeme[0])) { token->type = TID_NEWLINE; if(!tokens->empty() && tokens->back()->type == TID_NEWLINE) ignore = true; } else if(lexeme.size() == 1 && lexeme[0] == openBracket) token->type = TID_LBRACKET; else if(lexeme.size() == 1 && lexeme[0] == closeBracket) token->type = TID_RBRACKET; else if(lexeme.size() == 1 && lexeme[0] == colon) token->type = TID_COLON; else if(lexeme[0] == var) token->type = TID_VARIABLE; else { // This is either a non-zero length phrase or quoted phrase if(lexeme.size() >= 2 && lexeme[0] == quote && lexeme[lexeme.size() - 1] == quote) { token->type = TID_QUOTE; } else { token->type = TID_WORD; } } if(!ignore) tokens->push_back(token); }
bool CScanner::ParseStringLiteral() { UpdateCurrentToken(); string TempString = ""; while (cget() != '"' && cget() != 0) { if (isNewline()) { ErrorString = "Newline in string literal."; return false; } if (cget() == '\\') { IncPos(); if (cget() == 'x') { IncPos(); string VeryTempString = "x"; while(isxdigit(cget())) VeryTempString += cget(), IncPos(); try { TempString += EscapeSequenceToValue(VeryTempString); continue; } catch (positive_overflow &e) { ErrorString = "Hexadecimal constant is invalid (may be too large for character)."; return false; } } else { TempString += EscapeSequenceToValue(string() += cget()); IncPos(); continue; } } TempString += cget(); IncPos(); } IncPos(); CurrentToken.Kind = DTM_TOKEN::LITERAL::STRING; CurrentToken.Value = TempString; return true; }
static void seekUntilNewline(UCHARBUF* buf, struct UString *token, UErrorCode *status) { UChar32 c; if (U_FAILURE(*status)) { return; } do { c = ucbuf_getc(buf,status); /* add the char to token */ if(token!=NULL){ ustr_u32cat(token, c, status); } } while (!isNewline(c) && c != U_EOF && *status == U_ZERO_ERROR); }
/** * @brief Generates a string buffer from the current cursor position. * * A string buffer is closed when a @p endMarker is detected on an * empty line at the indentation of @p baseInd. When the function is * over, the parser cursor is at the character just after the closing marker. * * @param baseInd The indentation at which end marker is checked and the * number of whitespace to skip for each line of data. * @param endMarker Character that marks the end of a buffer. * * @return true if an error occurred, false otherwise. */ bool NepParser::helpGenBuffer(std::string& arg, size_t baseInd, char endMarker) { size_t stLine = getCurLine(), stCol = getCurCol(); int curTab = baseInd; int lineStart = getCurPos(); while( notEof() ) { char ch = getCurRaw(); if(curTab<=0) { if(isNewline(ch)) { std::string line = getSubString(lineStart, getCurPos()+1); line[line.size()-1] = '\n'; arg.append( line ); curTab = baseInd; lineStart=getCurPos()+1; } iterCur(); } else if( isSpace(ch) ) { curTab--; if(curTab<=0) lineStart=getCurPos()+1; iterCur(); } else if( ch == endMarker ) { // Move past the end marker iterCur(); if(arg.size()>0) arg.erase(arg.size()-1); return false; } else { curTab=0; lineStart=getCurPos(); } } mScript.addError(Nepeta::ErrBlockNoClosing, "", stLine,stCol, getCurLine(), getCurCol()); return true; }
void tail(FILE *file) { int lineNumber = 0; char *lineBuffer[11]; char **currentLine = &lineBuffer[0]; memset(lineBuffer, 0, sizeof(lineBuffer)); for (int c; (c = getc(file)) != EOF;) { expandAndAppend(currentLine, c); if (isNewline(c)) { lineNumber++; currentLine = &lineBuffer[lineNumber % 11]; free(*currentLine); *currentLine = NULL; } } for (int i = 0; i < 11; i++) printAndFreeLineIfNotNull(&lineBuffer[(i + lineNumber) % 11]); }
static void seekUntilEndOfComment(UCHARBUF *buf, struct UString *token, UErrorCode *status) { UChar32 c, d; uint32_t line; if (U_FAILURE(*status)) { return; } line = lineCount; do { c = ucbuf_getc(buf, status); if (c == ASTERISK) { d = ucbuf_getc(buf, status); if (d != SLASH) { ucbuf_ungetc(d, buf); } else { break; } } /* add the char to token */ if(token!=NULL){ ustr_u32cat(token, c, status); } /* increment the lineCount */ isNewline(c); } while (c != U_EOF && *status == U_ZERO_ERROR); if (c == U_EOF) { *status = U_INVALID_FORMAT_ERROR; error(line, "unterminated comment detected"); } }
Token* PreprocessorLexer::createTextToken(const std::streampos& start, const std::streampos& end) { // copy the number of characters to the buffer // std::streamsize count = (end - std::streampos(1) - start); char* buffer = 0; if (count > 0) { buffer = new char[static_cast<size_t>(count) + 1]; stream_->seekg(start, std::ios_base::beg); stream_->get(buffer, count + 1, char(255)); // char(255) prevents get() to stop at newlines. stream_->seekg(end, std::ios_base::beg); buffer[count] = 0; } else return 0; if (buffer != 0) { // Return a special 'newline' token, if the text only contains newlines. // Those tokens are required to terminate preprocessor directives // bool newlinesOnly = true; for (int i = 0; ((newlinesOnly) && (i < static_cast<int>(count))); ++i) { if (buffer[i] != 0) newlinesOnly = isNewline(buffer[i]); } Token* token = 0; if (! newlinesOnly) token = new TextToken(PreprocessorTerminals::ID_TEXT, std::string(buffer, static_cast<size_t>(count))); delete [] buffer; return token; } return new TextToken(PreprocessorTerminals::ID_TEXT, ""); }
/** * @brief Makes the parser skip until the next newline. * * After a call to this, the parser cursor is at the beginning * of the next line. * * @param checkWhite If true, an error message is raised if any * non-whitespace character occurs. * * @return true if an error occurred, else false. */ bool NepParser::helpSeekNewline(bool checkWhite) { bool ret = false; while( notEof() ) { char ch = getCurRaw(); if( isNewline(ch) ) { break; } else if( checkWhite && !isSpace(ch) ) { mScript.addError(Nepeta::WarnReqNewline, "", getCurLine(), getCurCol()); checkWhite=false; ret = true; } iterCur(); } // Skips the newline character to the next line iterCur(); return ret; }
ScriptTokenListPtr ScriptLexer::tokenize(const String &str, const String &source) { // State enums enum{ READY = 0, COMMENT, MULTICOMMENT, WORD, QUOTE, VAR, POSSIBLECOMMENT }; // Set up some constant characters of interest const wchar_t varopener = '$', quote = '\"', slash = '/', backslash = '\\', openbrace = '{', closebrace = '}', colon = ':', star = '*', cr = '\r', lf = '\n'; char c = 0; String lexeme; uint32 line = 1, state = READY, lastQuote = 0; ScriptTokenListPtr tokens(OGRE_NEW_T(ScriptTokenList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); // Iterate over the input String::const_iterator i = str.begin(), end = str.end(); while(i != end) { char lastc = c; c = *i; if(c == quote) lastQuote = line; switch(state) { case READY: if(c == slash && lastc == slash) { // Comment start, clear out the lexeme lexeme = ""; state = COMMENT; } else if(c == star && lastc == slash) { lexeme = ""; state = MULTICOMMENT; } else if(c == quote) { // Clear out the lexeme ready to be filled with quotes! lexeme = c; state = QUOTE; } else if(c == varopener) { // Set up to read in a variable lexeme = c; state = VAR; } else if(isNewline(c)) { lexeme = c; setToken(lexeme, line, source, tokens.get()); } else if(!isWhitespace(c)) { lexeme = c; if(c == slash) state = POSSIBLECOMMENT; else state = WORD; } break; case COMMENT: // This newline happens to be ignored automatically if(isNewline(c)) state = READY; break; case MULTICOMMENT: if(c == slash && lastc == star) state = READY; break; case POSSIBLECOMMENT: if(c == slash && lastc == slash) { lexeme = ""; state = COMMENT; break; } else if(c == star && lastc == slash) { lexeme = ""; state = MULTICOMMENT; break; } else { state = WORD; } case WORD: if(isNewline(c)) { setToken(lexeme, line, source, tokens.get()); lexeme = c; setToken(lexeme, line, source, tokens.get()); state = READY; } else if(isWhitespace(c)) { setToken(lexeme, line, source, tokens.get()); state = READY; } else if(c == openbrace || c == closebrace || c == colon) { setToken(lexeme, line, source, tokens.get()); lexeme = c; setToken(lexeme, line, source, tokens.get()); state = READY; } else { lexeme += c; } break; case QUOTE: if(c != backslash) { // Allow embedded quotes with escaping if(c == quote && lastc == backslash) { lexeme += c; } else if(c == quote) { lexeme += c; setToken(lexeme, line, source, tokens.get()); state = READY; } else { // Backtrack here and allow a backslash normally within the quote if(lastc == backslash) lexeme = lexeme + "\\" + c; else lexeme += c; } } break; case VAR: if(isNewline(c)) { setToken(lexeme, line, source, tokens.get()); lexeme = c; setToken(lexeme, line, source, tokens.get()); state = READY; } else if(isWhitespace(c)) { setToken(lexeme, line, source, tokens.get()); state = READY; } else if(c == openbrace || c == closebrace || c == colon) { setToken(lexeme, line, source, tokens.get()); lexeme = c; setToken(lexeme, line, source, tokens.get()); state = READY; } else { lexeme += c; } break; } // Separate check for newlines just to track line numbers if(c == cr || (c == lf && lastc != cr)) line++; i++; } // Check for valid exit states if(state == WORD || state == VAR) { if(!lexeme.empty()) setToken(lexeme, line, source, tokens.get()); } else { if(state == QUOTE) { OGRE_EXCEPT(Exception::ERR_INVALID_STATE, Ogre::String("no matching \" found for \" at line ") + Ogre::StringConverter::toString(lastQuote), "ScriptLexer::tokenize"); } } return tokens; }
void Lexer::consumeLineComment() { consume(); // First slash consume(); // Second slash while(!(isNewline() || isEof())) consume(); }
Token *Lexer::scanNewline() { startToken(); do consume(); while(isNewline() || isSpace()); return finishToken(Token::Newline); }
Token* PreprocessorLexer::scan() { if (scanState_ == STATE_END) return 0; // TODO: add correct line number and char position to returned token Token* token = 0; std::streampos stringStart = stream_->tellg(); try { while (token == 0) { switch (scanState_) { case STATE_START: scanState_ = STATE_SKIPPING_WHITESPACE; // no break here case STATE_SKIPPING_WHITESPACE: do { readChar(); } while (isWhitespace(peek_)); break; case STATE_INSIDE_BLOCK_COMMENT: for (int i = 0; i < 2; ) { readChar(); switch (peek_) { case '*': if (i == 0) i = 1; break; case '/': if (i == 1) i = 2; break; default: i = 0; } } scanState_ = STATE_START; break; case STATE_INSIDE_LINE_COMMENT: do { readChar(); } while (! isNewline(peek_)); scanState_ = STATE_START; break; case STATE_READING_DIRECTIVE: // If the tokens which are held from scanning the last directive // are empty, then we need to scan a new directive and keep it as // the current one until all tokens from it are processed // if (currentDirective_.empty()) { // read the directive // std::string directive; try { do { if (peek_ != 0) directive += peek_; readChar(); // if a backslash preceeds a newline, the directive does not end // yet, so remove any further newlines (and whitespace) // if ((peek_ == '\\') && (isNewline(stream_->peek()) == true)) { do { readChar(); } while (isWhitespace(peek_)); directive += ' '; } } while (isNewline(peek_) == false); currentDirective_ = scanDirective(directive); currentDirective_.push_back(new Token(PreprocessorTerminals::ID_NEWLINE)); // Catch runtime errors and create a token from the parts of the directive // which have already been read. This happens for instance, if a directive // is the last occurance in the current stream. // } catch (std::runtime_error&) { if (! directive.empty()) { currentDirective_ = scanDirective(directive); currentDirective_.push_back(new Token(PreprocessorTerminals::ID_NEWLINE)); } else { // There is nothing left within the stream so prepare to // reset the scanner and tell it to not emit any further // text token by adjusting the start position for scanning. // stream_->seekg(0, std::ios_base::end); stringStart = stream_->tellg(); scanState_ = STATE_START; } } } // if (currentDirective_.empty() // If the last scanned directive is not finished yet, return the first // token from it until it is empty. Afterwards reset the scanner. // if (! currentDirective_.empty()) { token = currentDirective_.front(); currentDirective_.pop_front(); // If the last token from the directive has been taken, // start new scanning // if (currentDirective_.empty()) scanState_ = (stream_->eof()) ? STATE_END : STATE_START; } break; default: readChar(); break; } // switch (scanState) switch (peek_) { case '/': if (readCharConditioned('/') == true) scanState_ = STATE_INSIDE_LINE_COMMENT; else if (readCharConditioned('*') == true) scanState_ = STATE_INSIDE_BLOCK_COMMENT; break; case '#': // create a token containing the text read up to here token = createTextToken(stringStart, stream_->tellg()); scanState_ = STATE_READING_DIRECTIVE; break; case '\\': if (readCharConditioned(&isNewline) == true) scanState_ = STATE_SKIPPING_WHITESPACE; break; } // switch (peek_) } // while (token == 0) // In case we created a runtime error by reading up to the end of the stream, // we have to create a TextToken for the remaining characters. // In addition, the scanner ist put to state STATE_END in order to indicate // the end of its work. // } catch (std::runtime_error&) { if (stream_->eof() == true) { scanState_ = STATE_END; stream_->clear(); stream_->seekg(0, std::ios_base::end); if (token == 0) token = createTextToken(stringStart, (stream_->tellg() + std::streampos(1))); } return token; } return token; }
int GetIdentPort(pid_t childPid) { string lsof = StringFormat::Fmt("lsof -p %d -a -i 4 -F n", (int)childPid); string result = execcmd(lsof.c_str()); // Parse the result expecting: // p<PID> // n*:<PORT> const size_t len = result.length(); bool found = false; if(result[0] == 'p') { size_t i = 1; for(; i < len; i++) { if(result[i] < '0' || result[i] > '9') break; } result[i++] = 0; if(isNewline(result[i])) i++; const int pid = std::stoi(&result[1]); if(pid == (int)childPid) { while(i < len) { if(result[i] == 'n') { char *portStr = NULL; for(; i < len; i++) { if(result[i] == ':') { portStr = &result[i + 1]; } if(isNewline(result[i])) { result[i++] = 0; if(i < len && isNewline(result[i])) result[i++] = 0; break; } } const int port = std::stoi(portStr); if(port >= RenderDoc_FirstTargetControlPort && port <= RenderDoc_LastTargetControlPort) { return port; } // continue on to next port } else { RDCERR("Malformed line - expected 'n':\n%s", &result[i]); break; } } } else { RDCERR("pid from lsof output doesn't match childPid"); } } else { RDCERR("lsof output doesn't begin with p<PID>:\n%s", &result[0]); } return 0; }
Token DefaultLexer::readToken() { char c = lookChar(); while (true) { // skip whitespace while (isWhiteSpace(c)) { skipChar(); c = lookChar(); } // newlines if (isNewline(c)) { readNewline(c); if (interactive_ && getCurrentBraceNesting() == 0) return Token(TK_Newline); c = lookChar(); continue; } // treat line comments as newlines if (c == '/' && lookChar(1) == '/') { readLineComment(); c = lookChar(); continue; } break; } SourceLocation sloc = getCurrentLocation(); // punctuation if (c == '(') { skipChar(); signalOpenBrace(TK_LParen); return Token(TK_LParen, "(", sloc); } if (c == ')') { skipChar(); signalCloseBrace(TK_LParen); return Token(TK_RParen, ")", sloc); } if (c == '{') { skipChar(); signalOpenBrace(TK_LCurlyBrace); return Token(TK_LCurlyBrace, "{", sloc); } if (c == '}') { skipChar(); signalCloseBrace(TK_LCurlyBrace); return Token(TK_RCurlyBrace, "}", sloc); } if (c == '[') { skipChar(); signalOpenBrace(TK_LSquareBrace); return Token(TK_LSquareBrace, "[", sloc); } if (c == ']') { skipChar(); signalCloseBrace(TK_LSquareBrace); return Token(TK_RSquareBrace, "]", sloc); } if (c == ',') { skipChar(); return Token(TK_Comma, ",", sloc); } if (c == ';') { skipChar(); return Token(TK_Semicolon, ";", sloc); } if (c == ':' && !isOperatorChar(lookChar(1))) { skipChar(); return Token(TK_Colon, ":", sloc); } if (c == '.') { skipChar(); return Token(TK_Period, ".", sloc); } // identifiers if (isLetter(c)) { readIdentifier(c); StringRef str = copyStr(finishToken()); unsigned keyid = lookupKeyword(str.c_str()); if (keyid) { return Token(keyid, str, sloc); } return Token(TK_Identifier, str, sloc); } // generic operators if (isOperatorChar(c)) { readOperator(c); StringRef str = copyStr(finishToken()); unsigned keyid = lookupKeyword(str.c_str()); if (keyid) { return Token(keyid, str, sloc); } return Token(TK_Operator, str, sloc); } // numbers if (isDigit(c)) { readInteger(c); StringRef str = copyStr(finishToken()); return Token(TK_LitInteger, str, sloc); } // characters if (c == '\'') { if (!readCharacter()) return Token(TK_Error); StringRef str = copyStr(finishToken()); return Token(TK_LitCharacter, str, sloc); } // strings if (c == '\"') { if (!readString()) return Token(TK_Error); StringRef str = copyStr(finishToken()); return Token(TK_LitString, str, sloc); } // if we're out of buffer, put in an EOF token. if (c == 0 || stream_eof()) { return Token(TK_EOF, "", sloc); } // Can't get the next token -- signal an error and bail. signalLexicalError(); return Token(TK_Error, "", sloc); }
bool GUIInputCaret::isCaretAtNewline() const { return isNewline(mCaretPos); }
void StripComments::process(char16_t c) { if (isNewline(c)) { // No matter what state we are in, pass through newlines // so we preserve line numbers. emit(c); if (m_parseState != InMultiLineComment) m_parseState = BeginningOfLine; return; } char16_t temp = 0; switch (m_parseState) { case BeginningOfLine: // If it's an ASCII space. if (c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9))) { emit(c); break; } if (c == '#') { m_parseState = InPreprocessorDirective; emit(c); break; } // Transition to normal state and re-handle character. m_parseState = MiddleOfLine; process(c); break; case MiddleOfLine: if (c == '/' && peek(temp)) { if (temp == '/') { m_parseState = InSingleLineComment; emit(' '); advance(); break; } if (temp == '*') { m_parseState = InMultiLineComment; // Emit the comment start in case the user has // an unclosed comment and we want to later // signal an error. emit('/'); emit('*'); advance(); break; } } emit(c); break; case InPreprocessorDirective: // No matter what the character is, just pass it // through. Do not parse comments in this state. This // might not be the right thing to do long term, but it // should handle the #error preprocessor directive. emit(c); break; case InSingleLineComment: // The newline code at the top of this function takes care // of resetting our state when we get out of the // single-line comment. Swallow all other characters. break; case InMultiLineComment: if (c == '*' && peek(temp) && temp == '/') { emit('*'); emit('/'); m_parseState = MiddleOfLine; advance(); break; } // Swallow all other characters. Unclear whether we may // want or need to just emit a space per character to try // to preserve column numbers for debugging purposes. break; } }
inline bool isWhitespace(uint32_t c) { return c == '\t' || c == ' ' || isNewline(c) || (c > 128 && (charClass(c) & CharClass::Separator) != 0); }
int INIParser::parse() { char ch; char buffer[100]; int i = 0; int line = 1; std::string section = "__NO_SECTION__"; std::string name; parseState = NO_SECTION; // open ini file std::ifstream in(_iniFile.c_str(), std::ios::in | std::ios::binary); while ( in.get(ch) ) { switch (ch) { case '[' : if (isStartSection()) return line; if ( i == 0 ) parseState = START_SECTION; else return line; break; case ']' : if (isStopSection()) return line; if (isStartSection() && i > 0) { buffer[i] = '\0'; section = buffer; //std::cout << "section => " << buffer << std::endl; i=0; } else { // else error , empty section [] or ] not the end of start section return line; } parseState = STOP_SECTION; break; case '=' : if ( isStartSection() || isDelimiter()) return line; if ( isNoSection() && i == 0 ) return line; if ((isNewline() || isNoSection()) && i > 0) { buffer[i] = '\0'; name = buffer; //std::cout << "key => " << buffer << std::endl; i=0; } else if (isNewline() && i == 0) return line; parseState = DELIMITER; break; case '\n' : if ( isNewline() && i > 0 ) return line; if ( isNoSection() && i > 0 ) return line; if ( isStartSection() ) return line; if ( isDelimiter() && i > 0 ) { buffer[i] = '\0'; sections[section][name] = buffer; //std::cout << "value => " << buffer << std::endl; i=0; } else if ( isDelimiter() && i == 0 ) return line; //if ( parseState != DELIMITER || parseState != STOP_SECTION || parseState != COMMENT ) // return line; parseState = NEWLINE; line++; break; case ';' : parseState = COMMENT; break; case '#' : parseState = COMMENT; break; case ' ' : break; default : if ( isNewline() || isNoSection() ) { buffer[i] = ch; i++; } if ( isDelimiter() ) { buffer[i] = ch; i++; } if ( isStartSection() ) { buffer[i] = ch; i++; } // else error break; } } in.close(); return 0; }
/// Any whitespace (space or newline) bool NepParser::isWhite(char ch) { return isSpace(ch) || isNewline(ch); }