Esempio n. 1
0
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() );
}
Esempio n. 2
0
/*
*  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...
  }
}
Esempio n. 4
0
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());
}
Esempio n. 5
0
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++;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
// 函数块
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);
        }
    }
}
Esempio n. 8
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;
}
Esempio n. 9
0
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() );
}
Esempio n. 10
0
void DSNLEXER::Unexpected( int aTok ) throw( IO_ERROR )
{
    wxString    errText( _("Unexpected") );
    errText << wxT(" ") << GetTokenString( aTok );
    THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
}