/* Description- parses the command in a command line. GET- line (line info *). (IC, DC). */ void parseCommand(lineInfo *line, int *IC, int *DC) { int cmdId = getCmdId(line->commandStr); if (cmdId == -1) { line->cmd = NULL; if (*line->commandStr == '\0') { /* The command is empty, but the line isn't empty so it's only a label. */ printf("ERR:\tCan't write a label to an empty line: %d.\n", line->lineNum); ERROR = TRUE; } else { /* Illegal command. */ printf("ERR:\tNo such command as. line: %d.\n", line->lineNum); ERROR = TRUE; } return; } line->cmd = &g_cmdArr[cmdId]; parseCmdOperands(line, IC, DC); }
// Parsing relies on the std:isw* family of functions doing the "right thing" // Otherwise, we'd use the SBCS/DBCS tables from the *.nls files as parsed in // the nls object Lexer::Token Lexer::lex( IpfData* input ) { Token type( END ); if( input ) { wchar_t ch; wchar_t quoteChar; bool inQuote( false ); buffer.clear(); charNum = input->currentCol(); lineNum = input->currentLine(); while( ( ch = input->get() ) != EOB ) { buffer.push_back( ch ); if( inTag ) { if( type == END ) { //first char after tag name if( ch == L'.' ) { type = TAGEND; inTag = false; break; } else if( std::iswspace( ch ) ) //ignore leading whitespace buffer.erase( buffer.size() - 1 ); else if( std::iswalpha( ch ) ) { type = FLAG; //tentatively inQuote = false; } } else { if( !inQuote && ch == L'.' ) { input->unget( ch ); buffer.erase( buffer.size() - 1 ); break; } else if( !inQuote && ch == L':' ) { //syntax error type = ERROR_TAG; break; } else if ( type == FLAG ) { if( ch == L'=' ) type = ATTRIBUTE; else if( std::iswspace( ch ) ) { buffer.erase( buffer.size() - 1 ); break; } } else if ( type == ATTRIBUTE ) { if( ch == L'\'' || ch == '\"' ) { if( !inQuote ) { inQuote = true; quoteChar = ch; } else if( ch == quoteChar ) { inQuote = false; } } else if( !inQuote && std::iswspace( ch ) ) { buffer.erase( buffer.size() - 1 ); break; } } else if( std::iswspace( ch ) ) { //ignore trailing space buffer.erase( buffer.size() - 1 ); break; } } } else { if( type == END ) { //first character of token if( std::iswspace( ch ) ) { type = WHITESPACE; if( ch == L'\n' ) //don't concatenate spaces break; } else if ( ch == L':' ) { wchar_t ch2( input->get() ); input->unget( ch2 ); if( std::iswalpha( ch2 ) ) { type = TAG; inTag = true; } else { type = PUNCTUATION; break; } } else if ( ch == L'&' ) { wchar_t ch2( input->get() ); input->unget( ch2 ); if( std::iswalnum( ch2 ) ) type = ENTITY; else type = WORD; } else if ( ch == L'.' ) { if( charNum == 1 ) type = COMMAND; else { type = PUNCTUATION; break; } } else if ( std::iswpunct( ch ) ) { //single character, but not '.' or '&' or ':' type = PUNCTUATION; break; } else //if ( std::iswalnum( ch ) ) type = WORD; } else { if( type == COMMAND ) { if( ch == L'\n' ) { break; } } else if( ch == L':' || ch == L'&' ) { //beginning of another token input->unget( ch ); buffer.erase( buffer.size() - 1 ); if( type == ENTITY ) type = ERROR_ENTITY; //'.' not found break; } else if( type == ENTITY ) { if( ch == L'.' ) //end of entity break; if( !std::iswalnum( ch ) ) { //non-fatal malformed entity input->unget( ch ); buffer.erase( buffer.size() - 1 ); type = ERROR_ENTITY; break; } } else if( type == WHITESPACE && ( !std::iswspace( ch ) || ch == L'\n' ) ) { //end of whitespace //don't concatenate \n's input->unget( ch ); buffer.erase( buffer.size() - 1 ); break; } else if( type == WORD && ( std::iswspace( ch ) || std::iswpunct( ch ) ) ) { //!std::iswalnum( ch ) //end of token input->unget( ch ); buffer.erase( buffer.size() - 1 ); break; } } } } if ( type == TAG ) getTagId(); else if ( type == COMMAND ) getCmdId(); } return type; }