void DSNLEXER::Duplicate( int aTok ) throw( IO_ERROR ) { wxString errText; errText.Printf( _("%s is a duplicate"), GetTokenString( aTok ).GetData() ); THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() ); }
/* * CLinePtr::RpSetCp(cp, fAtEnd) * * Purpose * Set this line ptr to cp allowing for ambigous cp and taking advantage * of _cpFirstVisible and _iliFirstVisible * * Arguments: * cp position to set this line ptr to * fAtEnd if ambiguous cp: * if fAtEnd = TRUE, set this line ptr to end of prev line; * else set to start of line (same cp, hence ambiguous) * Return: * TRUE iff able to set to cp */ BOOL CLinePtr::RpSetCp(LONG cp, BOOL fAtEnd, BOOL fSkipFrame) { Assert(_prgRun); BOOL fRet; // Adjust the cp to be relative to the txt site containting the disp cp -= _pdp->GetFlowLayout()->GetContentFirstCp(); { SetIRun(0); SetIch(0); fRet = RpAdvanceCp(cp, fSkipFrame); // Start from 0 } // Note(SujalP): As exposed in bug 50281, it can happen that the containing // txtsite contains no lines. In which case we cannot really position // ourselves anywhere. Return failure. if(!CurLine()) { fRet = FALSE; } // Note(SujalP): Problem exposed in bug34660 -- when we are positioned at a // frame line, then the fAtEnd flag is really meaning less, since we base // our decision to move to prev or next line based on where in the line // is the cp positioned. Since, frame lines contain to characters, we really // cannot make that decision at all. else if(!CurLine()->IsFrame()) { // Ambiguous-cp caret position, should we be at the end of the line? if(fAtEnd) { if(!GetIch() && PrevLine(fSkipFrame, FALSE)) { SetIch(GetCurrRun()->_cch); // the first, go to end of } } // Or the beginning of the next one? else { if(GetIch()==long(GetCurrRun()->_cch) && NextLine(fSkipFrame, FALSE)) { SetIch(0); // Beginning of next line. } } } return fRet; }
////////////////////////////////////////////////////////////////////////// // // Skips spaces, tabs, newlines, and comments // void Tokenizer::SkipWhiteSpace() { while (isspace(CurrentCh) && CurrentCh ) { GetCh(); } if( '/' == CurrentCh ) // Look for comments { GetCh(); if( '/' == CurrentCh ) { // Throw out everything until the end of the line while( '\n' != CurrentCh ) { GetCh(); } } else if ( '*' == CurrentCh ) { int startLine = CurLine(); while( true ) { GetCh(); if( '*' == CurrentCh ) { GetCh(); if( CondReadCh( '/' ) ) break; else if ( buffer.isEOF() ) { std::ostringstream ost; ost << "Unterminated comment in line "; ost << startLine; throw SyntaxErrorException( ost.str(), *this ); } } else if ( buffer.isEOF() ) { std::ostringstream ost; ost << "Unterminated comment in line "; ost << startLine; throw SyntaxErrorException( ost.str(), *this ); } } } else { std::ostringstream ost; ost << "unexpected character: '" << CurrentCh << "'"; throw SyntaxErrorException( ost.str(), *this ); } SkipWhiteSpace(); // We may need to throw out // more white space/comments // This is admittedly tail recursion... } }
void CodeGenerator::match(string sym) { // 匹配函数 string Now = CodeToString(Tokens[CurToken]); if(Now == sym) { CurToken ++; } else { printf("in line [%d] : expect %s!\n", CurLine(), sym.c_str()); exit(0); } //printf("in Line [%d]:%d Match %s\n", CurLine(), CurToken, sym.c_str()); }
int CodeGenerator::addQuad(string op, string name1, string name2, string res) { if(!isDefined(name1) || !isDefined(name2)) { isError = true; if(!isDefined(name1)) Errors.push_back({ SemanticErrorType::UndeclaredSymbols, CurLine(), name1 + "该变量未定义" }); if(!isDefined(name2)) Errors.push_back({ SemanticErrorType::UndeclaredSymbols, CurLine(), name2 + "该变量未定义" }); return CurLabel; } if(VarTable.count(name1) && VarTable.count(name2) && VarTable[name1].Type != VarTable[name2].Type) { isError = true; Errors.push_back({ SemanticErrorType::TypeMismatch, CurLine(), VarTable[name1].Type + "与" + VarTable[name2].Type + "类型不匹配" }); return CurLabel; } QuadList.push_back({op, name1, name2, res}); return CurLabel++; }
int DSNLEXER::NeedNUMBER( const char* aExpectation ) throw( IO_ERROR ) { int tok = NextTok(); if( tok != DSN_NUMBER ) { wxString errText; errText.Printf( _("need a NUMBER for '%s'"), wxString::FromUTF8( aExpectation ).GetData() ); THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() ); } return tok; }
// 函数块 void CodeGenerator::Block() { while(!isNext("}")) { CodeToken T = getToken(); string value = T.value; if(value == "if") { If(); } else if(value == "while") { While(); } else if(value == "for") { For(); } else if(value == "read") { match("("); addQuad("read", getToken().value, "$", "$"); match(")"); match(";"); } else if(value == "write") { match("("); addQuad("write", getToken().value, "$", "$"); match(")"); match(";"); } else if(value == "return") { addQuad("return", itos(getToken().num), "$", "$"); match(";"); } else if(CodeToString(T) == "id") { CurToken--; Assign(); } else { puts("函数块错误!!"); printf("in %d", CurLine()); exit(0); } } }
int DSNLEXER::NextTok() throw( IO_ERROR ) { const char* cur = next; const char* head = cur; prevTok = curTok; if( curTok != DSN_EOF ) { if( cur >= limit ) { L_read: // blank lines are returned as "\n" and will have a len of 1. // EOF will have a len of 0 and so is detectable. int len = readLine(); if( len == 0 ) { cur = start; // after readLine(), since start can change, set cur offset to start curTok = DSN_EOF; goto exit; } cur = start; // after readLine() since start can change. // skip leading whitespace while( cur<limit && isSpace(*cur) ) ++cur; // If the first non-blank character is #, this line is a comment. // Comments cannot follow any other token on the same line. if( cur<limit && *cur=='#' ) { if( commentsAreTokens ) { // save the entire line, including new line as the current token. // the '#' character may not be at offset zero. curText = start; // entire line is the token cur = start; // ensure a good curOffset below curTok = DSN_COMMENT; head = limit; // do a readLine() on next call in here. goto exit; } else goto L_read; } } else { // skip leading whitespace while( cur<limit && isSpace(*cur) ) ++cur; } if( cur >= limit ) goto L_read; // switching the string_quote character if( prevTok == DSN_STRING_QUOTE ) { static const wxString errtxt( _("String delimiter must be a single character of ', \", or $")); char cc = *cur; switch( cc ) { case '\'': case '$': case '"': break; default: THROW_PARSE_ERROR( errtxt, CurSource(), CurLine(), CurLineNumber(), CurOffset() ); } curText = cc; head = cur+1; if( head<limit && *head!=')' && *head!='(' && !isSpace(*head) ) { THROW_PARSE_ERROR( errtxt, CurSource(), CurLine(), CurLineNumber(), CurOffset() ); } curTok = DSN_QUOTE_DEF; goto exit; } if( *cur == '(' ) { curText = *cur; curTok = DSN_LEFT; head = cur+1; goto exit; } if( *cur == ')' ) { curText = *cur; curTok = DSN_RIGHT; head = cur+1; goto exit; } /* get the dash out of a <pin_reference> which is embedded for example like: U2-14 or "U2"-"14" This is detectable by a non-space immediately preceeding the dash. */ if( *cur == '-' && cur>start && !isSpace( cur[-1] ) ) { curText = '-'; curTok = DSN_DASH; head = cur+1; goto exit; } // handle DSN_NUMBER if( strchr( "+-.0123456789", *cur ) ) { head = cur+1; while( head<limit && strchr( ".0123456789", *head ) ) ++head; if( (head<limit && isSpace(*head)) || *head==')' || *head=='(' || head==limit ) { curText.clear(); curText.append( cur, head ); curTok = DSN_NUMBER; goto exit; } // else it was something like +5V, fall through below } // a quoted string, will return DSN_STRING if( *cur == stringDelimiter ) { // Non-specctraMode, understands and deciphers escaped \, \r, \n, and \". // Strips off leading and trailing double quotes if( !specctraMode ) { // copy the token, character by character so we can remove doubled up quotes. curText.clear(); ++cur; // skip over the leading delimiter, which is always " in non-specctraMode head = cur; while( head<limit ) { // ESCAPE SEQUENCES: if( *head =='\\' ) { char tbuf[8]; char c; int i; if( ++head >= limit ) break; // throw exception at L_unterminated switch( *head++ ) { case '"': case '\\': c = head[-1]; break; case 'a': c = '\x07'; break; case 'b': c = '\x08'; break; case 'f': c = '\x0c'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\x09'; break; case 'v': c = '\x0b'; break; case 'x': // 1 or 2 byte hex escape sequence for( i=0; i<2; ++i ) { if( !isxdigit( head[i] ) ) break; tbuf[i] = head[i]; } tbuf[i] = '\0'; if( i > 0 ) c = (char) strtoul( tbuf, NULL, 16 ); else c = 'x'; // a goofed hex escape sequence, interpret as 'x' head += i; break; default: // 1-3 byte octal escape sequence --head; for( i=0; i<3; ++i ) { if( head[i] < '0' || head[i] > '7' ) break; tbuf[i] = head[i]; } tbuf[i] = '\0'; if( i > 0 ) c = (char) strtoul( tbuf, NULL, 8 ); else c = '\\'; // a goofed octal escape sequence, interpret as '\' head += i; break; } curText += c; } else if( *head == '"' ) // end of the non-specctraMode DSN_STRING { curTok = DSN_STRING; ++head; // omit this trailing double quote goto exit; } else curText += *head++; } // while // L_unterminated: wxString errtxt(_("Un-terminated delimited string") ); THROW_PARSE_ERROR( errtxt, CurSource(), CurLine(), CurLineNumber(), CurOffset() ); } else // specctraMode DSN_STRING { ++cur; // skip over the leading delimiter: ",', or $ head = cur; while( head<limit && !isStringTerminator( *head ) ) ++head; if( head >= limit ) { wxString errtxt(_("Un-terminated delimited string") ); THROW_PARSE_ERROR( errtxt, CurSource(), CurLine(), CurLineNumber(), CurOffset() ); } curText.clear(); curText.append( cur, head ); ++head; // skip over the trailing delimiter curTok = DSN_STRING; goto exit; } } // Maybe it is a token we will find in the token table. // If not, then call it a DSN_SYMBOL. { head = cur+1; while( head<limit && !isSpace( *head ) && *head!=')' && *head!='(' ) ++head; curText.clear(); curText.append( cur, head ); int found = findToken( curText ); if( found != -1 ) curTok = found; else if( 0 == curText.compare( "string_quote" ) ) curTok = DSN_STRING_QUOTE; else // unrecogized token, call it a symbol curTok = DSN_SYMBOL; } } exit: // single point of exit, no returns elsewhere please. curOffset = cur - start; next = head; // printf("tok:\"%s\"\n", curText.c_str() ); return curTok; }
void DSNLEXER::Unexpected( const char* text ) throw( IO_ERROR ) { wxString errText( _("Unexpected") ); errText << wxT(" '") << wxString::FromUTF8( text ) << wxT("'"); THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() ); }
void DSNLEXER::Unexpected( int aTok ) throw( IO_ERROR ) { wxString errText( _("Unexpected") ); errText << wxT(" ") << GetTokenString( aTok ); THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() ); }