Exemplo n.º 1
0
void ParserThread::HandleClass(EClassType ct)
{

    // class xxx {   or class {
    // the keyworkd "class" is already comsumed

    //assert(CurrentToken()->type_id()==TKN_CLASS);
    ConsumeToken();


    Token * current =  ConsumeToken();      // class name
    Token * next    =  PeekToken();

    TRACE("HandleClass() : Found class '%s'", current->get_text().c_str() );


    // Check current firstly
    if (current->type_id() == TKN_L_BRACE)   // unnamed class/struct/union
    {
//                cc_string unnamedTmp;
//                unnamedTmp.Printf(_T("%s%s%d"),
//                                  ParserConsts::unnamed.wx_str(),
//                                  ct == ctClass ? _T("Class") :
//                                  ct == ctUnion ? _T("Union") :
//                                                  _T("Struct"), ++m_pTokensTree->m_StructUnionUnnamedCount);
//
//                Token* newToken = DoAddToken(tkClass, unnamedTmp, lineNr);
//
//                PushContext();
//                m_Context.Clear();
//                m_Context.parentToken = newToken;
//                m_Context.accessScope  = ct == ctClass ? tsPrivate : tsPublic; // struct has default public scope
//
//				newToken->m_ImplLine = lineNr;
//				newToken->m_ImplLineStart = m_Tokenizer.GetLineNumber();
//
//                DoParse();
//
//                PopContext();
    }
    else if (current->type_id() == TKN_IDENTIFIER)     //OK, we need to check the next
    {
        //parser base clause
        if ( next->type_id() == TKN_COLON )
        {
            //ReadType
            //ConsumeToken(); //remove :id
            ConsumeToken(); //remove  :
            ConsumeToken(); //remove protect/public/private
            //ConsumeToken(); //need to read the id
            ParseFullIdentifer();
        }
        next = PeekToken();
        if ( next->type_id() == TKN_L_BRACE)   // class AAA {, we find the "{" here
        {

            //ParserThreadContext savedContext = m_Context;
            //m_Context.EndStatement();
            //m_Context.parentToken = newToken;
            ConsumeToken();// consume {
            Symbol * sym = DoAddToken(tkClass, *current);
            PushContext();
            m_Context.parentToken = sym;
            DoParse();  // when meet a }, we should return from DoParse()
            PopContext();
            current = ConsumeToken();
            if(current->type_id()==TKN_SEMICOLON)  // class A {.....};
                return;
            else
                SkipStatementBlock(); //struct A {....} a b;

        }
    }
    else
    {
        // something wrong, should be skip to a semicolon
        SkipStatementBlock();
    }

}
Exemplo n.º 2
0
/// ParseDeclarationTypeSpec - Parse a declaration type spec construct.
/// 
///   [R502]:
///     declaration-type-spec :=
///         intrinsic-type-spec
///      or TYPE ( derived-type-spec )
///      or CLASS ( derived-type-spec )
///      or CLASS ( * )
bool Parser::ParseDeclarationTypeSpec(DeclSpec &DS, bool AllowSelectors,
                                      bool AllowOptionalCommaAfterCharLength) {
  // [R403]:
  //   intrinsic-type-spec :=
  //       INTEGER [ kind-selector ]
  //    or REAL [ kind-selector ]
  //    or DOUBLE PRECISION
  //    or COMPLEX [ kind-selector ]
  //    or DOUBLE COMPLEX
  //    or CHARACTER [ char-selector ]
  //    or BYTE
  //    or LOGICAL [ kind-selector ]
  switch (Tok.getKind()) {
  default:
    DS.SetTypeSpecType(DeclSpec::TST_unspecified);
    break;
  case tok::kw_INTEGER:
    DS.SetTypeSpecType(DeclSpec::TST_integer);
    break;
  case tok::kw_REAL:
    DS.SetTypeSpecType(DeclSpec::TST_real);
    break;
  case tok::kw_COMPLEX:
    DS.SetTypeSpecType(DeclSpec::TST_complex);
    break;
  case tok::kw_CHARACTER:
    DS.SetTypeSpecType(DeclSpec::TST_character);
    break;
  case tok::kw_BYTE:
    DS.SetTypeSpecType(DeclSpec::TST_logical);
    DS.setByte(); // equivalent to Kind = 1
    break;
  case tok::kw_LOGICAL:
    DS.SetTypeSpecType(DeclSpec::TST_logical);
    break;
  case tok::kw_DOUBLEPRECISION:
    DS.SetTypeSpecType(DeclSpec::TST_real);
    DS.setDoublePrecision(); // equivalent to Kind = 8
    break;
  case tok::kw_DOUBLECOMPLEX:
    DS.SetTypeSpecType(DeclSpec::TST_complex);
    DS.setDoublePrecision(); // equivalent to Kind = 8
    break;
  }

  if (DS.getTypeSpecType() == DeclSpec::TST_unspecified)
    if (ParseTypeOrClassDeclTypeSpec(DS))
      return true;

  ExprResult Kind;
  ExprResult Len;

  // FIXME: no Kind for double complex, double precision and byte
  switch (DS.getTypeSpecType()) {
  case DeclSpec::TST_struct:
    break;
  default:
    ConsumeToken();
    if (ConsumeIfPresent(tok::star)) {
      // FIXME: proper obsolete COMPLEX*16 support
      ConsumeAnyToken();
      DS.setDoublePrecision();
    }

    if (!AllowSelectors)
      break;
    if (ConsumeIfPresent(tok::l_paren)) {
      Kind = ParseSelector(true);
      if (Kind.isInvalid())
        return true;

      if(!ExpectAndConsume(tok::r_paren, 0, "", tok::r_paren))
        return true;
    }

    break;
  case DeclSpec::TST_character:
    // [R424]:
    //   char-selector :=
    //       length-selector
    //    or ( LEN = type-param-value , KIND = scalar-int-initialization-expr )
    //    or ( type-param-value , #
    //    #    [ KIND = ] scalar-int-initialization-expr )
    //    or ( KIND = scalar-int-initialization-expr [, LEN = type-param-value])
    //
    // [R425]:
    //   length-selector :=
    //       ( [ LEN = ] type-param-value )
    //    or * char-length [,]
    //
    // [R426]:
    //   char-length :=
    //       ( type-param-value )
    //    or scalar-int-literal-constant
    //
    // [R402]:
    //   type-param-value :=
    //       scalar-int-expr
    //    or *
    //    or :
    ConsumeToken();

    if(ConsumeIfPresent(tok::star)) {
      ParseCharacterStarLengthSpec(DS);
      if(AllowOptionalCommaAfterCharLength)
        ConsumeIfPresent(tok::comma);
    } else {
      if (!AllowSelectors)
        break;
      if(ConsumeIfPresent(tok::l_paren)) {
        if(IsPresent(tok::kw_LEN)) {
          Len = ParseSelector(false);
          if (Len.isInvalid())
            return true;
        } else if(IsPresent(tok::kw_KIND)) {
          Kind = ParseSelector(true);
          if (Kind.isInvalid())
            return true;
        } else {
          Len = ParseExpectedFollowupExpression("(");
          if(Len.isInvalid())
            return true;
        }

        if(ConsumeIfPresent(tok::comma)) {
          // FIXME:
          if (Tok.is(tok::kw_LEN)) {
            if (Len.isInvalid())
              return Diag.ReportError(Tok.getLocation(),
                                      "multiple LEN selectors for this type");
            Len = ParseSelector(false);
            if (Len.isInvalid())
              return true;
          } else if (Tok.is(tok::kw_KIND)) {
            if (Kind.isInvalid())
              return Diag.ReportError(Tok.getLocation(),
                                      "multiple KIND selectors for this type");
            Kind = ParseSelector(true);
            if (Kind.isInvalid())
              return true;
          } else {
            if (Kind.isInvalid())
              return Diag.ReportError(Tok.getLocation(),
                                      "multiple KIND selectors for this type");

            ExprResult KindExpr = ParseExpression();
            Kind = KindExpr;
          }
        }

        if(!ExpectAndConsume(tok::r_paren))
          return true;
      }
    }

    break;
  }

  // Set the selectors for declspec.
  if(Kind.isUsable()) DS.setKindSelector(Kind.get());
  if(Len.isUsable())  DS.setLengthSelector(Len.get());
  return false;
}
Exemplo n.º 3
0
void ParserThread::DoParse()
{

    while (true)
    {
        Token* tk = PeekToken();

        switch (tk->type_id())
        {
        case TKN_L_BRACE: //{
        {
            SkipBrace();
            break;
        }
        case TKN_R_BRACE: //}
        {
            // the only time we get to find a } is when recursively called by e.g. HandleClass
            // we have to return now...
            TRACE("DoParse(): return from%s%d:%d",tk->get_string().c_str(),tk->line_number(),tk->column_number());
            ConsumeToken();
            return;
        }
        case TKN_R_PAREN: //)
        {
            TRACE("DoParse(): return from%s%d:%d",tk->get_string().c_str(),tk->line_number(),tk->column_number());
            ConsumeToken();
            if(m_Context.parseType==FunctionParameter
               && m_Context.typeQueue.size()>0
               && m_Context.nameQueue.size()>0)
            {
                DoAddToken(tkParameter, m_Context.nameQueue.back().name);
            }
            return;
        }
        case TKN_L_PAREN :       // (
        {
            SkipParentheses();
            break;
        }
        case TKN_FOR:
        case TKN_WHILE:
        case TKN_IF:
        case TKN_SWITCH:
        {
            TRACE("handling for or while block");
            HandleForWhile();
            break;
        }
        case TKN_ELSE:
        {
            ConsumeToken();
            if(PeekToken()->type_id()==TKN_IF)
            {
                ConsumeToken();
                HandleForWhile();
            }
            else
                SkipStatementBlock();
            break;
        }
        case TKN_CLASS:
        case TKN_STRUCT:
        {
            m_Context.EndStatement();
            if (m_Options.handleClasses)
                HandleClass(ctClass);
            else
                SkipStatementBlock();
            break;
        }

        case  TKN_EXPLICIT:
        case  TKN_CONST:
        case  TKN_FRIEND:
        case  TKN_VIRTUAL:
        case  TKN_VOLATILE:
        case  TKN_STATIC:
        case  TKN_INLINE:
        case  TKN_AUTO:
        case  TKN_REGISTER:
        case  TKN_MUTABLE:
        {
            ConsumeToken();
            //m_Context.typeQualifier = tk->type_id();
            break;
        }
        case TKN_IDENTIFIER:
        {
            ParseFullIdentifer();
            // we are interested in the following token.

            Token * peek = PeekToken();
            int peekID = peek-> type_id();
            switch (peekID)
            {
            case TKN_L_PAREN:      // This is a function definition or declration, because it has AAA BBB (

                if(m_Context.nameQueue.empty())   // AAA(
                {
                    //HandleMacro();
                    if(   m_Context.parentToken!= NULL
                       && m_Context.parentToken->m_SymbolKind == tkClass
                       && m_Context.parentToken->m_Name.get_text() == tk->get_text())
                        HandleFunction();
                    else
                    {
                        SkipParentheses();
                    }

                }
                else                            // AAA BBB(
                {
                    HandleFunction();
                }
                break;
            case  TKN_SEMICOLON:     // A B;
                if(m_Context.nameQueue.empty())   // AAA;
                {
                    SkipStatementBlock();
                }
                else                            // AAA BBB;
                {
                    // the last element of the m_Context.name is the actual variable name
                    cc_string variableName = m_Context.nameQueue.back().name.get_text();

                    // the last element of the m_Context.type is the actual type name
                    cc_string variableType = m_Context.typeQueue.back().name.get_text();

                    TRACE("Variable Find name(%s) type(%s)",variableName.c_str(),variableType.c_str());
                    //Add variable to tokenstree
                    if (m_Options.handleVars)
                        DoAddToken(tkVariable, m_Context.nameQueue.back().name);


                    ConsumeToken();    //consume the semicolon
                    m_Context.EndStatement();
                }
                break;
            case TKN_BITAND://&
                m_Context.typeQualifier.isReference = true;
                ConsumeToken();
                break;
            case TKN_MULT:  //*
                m_Context.typeQualifier.isPointer = true;
                ConsumeToken();
                break;
            case TKN_L_SQUARE:
            case TKN_PLUS:
            case TKN_PLUS_ASSIGN:
            case TKN_DOUBLE_PLUS:
            case TKN_MINUS:
            case TKN_DOUBLE_MINUS:
            case TKN_MINUS_ASSIGN:
            case TKN_MULT_ASSIGN:
            case TKN_DIV:
            case TKN_DIV_ASSIGN:
            case TKN_MODULO:
            case TKN_MODULO_ASSIGN:
            case TKN_L_SHIFT:
            case TKN_L_SHIFT_ASSIGN:
            case TKN_R_SHIFT:
            case TKN_R_SHIFT_ASSIGN:
            case TKN_DOT:
            case TKN_ARROW:
                ConsumeToken();
                SkipStatementBlock();
                break;

            case TKN_COMMA:
            case TKN_ASSIGN:
                // A B = ....;
                // A B,C,D=2;
                if(m_Context.nameQueue.empty())   // A,
                {
                    TRACE("Something wrong in mode A, ");
                    SkipStatementBlock();
                }
                else                            // A B,
                {
                    cc_string variableName = m_Context.nameQueue.back().name.get_text();
                    cc_string variableType = m_Context.typeQueue.back().name.get_text();
                    TRACE("Variable Find name(%s) type(%s)",variableName.c_str(),variableType.c_str());
                    //Add variable to tokenstree
                    if (m_Options.handleVars)
                    {
                        if(m_Context.parseType == FunctionParameter)
                            DoAddToken(tkParameter, m_Context.nameQueue.back().name);
                        else
                            DoAddToken(tkVariable, m_Context.nameQueue.back().name);
                    }

                    ConsumeToken();       //consume , or =

                    // tk is updated
                    if(peek->type_id()  == TKN_ASSIGN)
                    {
                        SkipStatementBlock();
                    }
                    else
                        m_Context.nameQueue.clear();  // clear name information, because we need to read another name

                }
                break;
            }
            break;
        }// End of handling of case TKN_IDENTIFIER
        case TKN_SEMICOLON:
        {
            ConsumeToken();
            m_Context.EndStatement();
            break;
        }
        case TKN_PUBLIC:
        {
            ConsumeToken();
            Token * peek = PeekToken();
            if(peek->type_id() == TKN_COLON)
            {
                m_Context.accessScope = tsPublic;
                m_Context.EndStatement();
                ConsumeToken();
            }
            break;
        }
        case TKN_PRIVATE:
        {
            ConsumeToken();
            Token * peek = PeekToken();
            if(peek->type_id() == TKN_COLON)
            {
                m_Context.accessScope = tsPrivate;
                m_Context.EndStatement();
                ConsumeToken();
            }
            break;
        }
        case TKN_PROTECT:
        {
            ConsumeToken();
            Token * peek = PeekToken();
            if(peek->type_id() == TKN_COLON)
            {
                m_Context.accessScope = tsProtected;
                m_Context.EndStatement();
                ConsumeToken();
            }
            break;
        }
        case TKN_USING:
        {
            ParseUsing();
            break;
        }
        case TKN_DELETE:
        case TKN_NEW:
        case TKN_RETURN:
        case TKN_EXTERN:
        case TKN_GOTO:
        {
            SkipStatementBlock();
            break;
        }
        case TKN_TEMPLATE:
        {
            bool readArgsOK = GetTemplateArgs();   // should following a <> pair,
            if(!readArgsOK)   //should return true, otherwise, we should
                SkipStatementBlock();
            break;
        }
        case TKN_ENUM:
        {
            if (m_Options.handleEnums)
                HandleEnum();
            else
                SkipStatementBlock();
            break;
        }
        case TKN_TYPEDEF:
        {
            if (m_Options.handleTypedefs)
                HandleTypedef();
            else
                SkipStatementBlock();
            m_Context.EndStatement();

            break;
        }
        case TKN_NAMESPACE:
        {
           HandleNamespace();
           break;
        }
        case TKN_OPERATOR:
        {
            ConsumeToken(); //eat the operator keyword
            Token *op = ConsumeToken();

            // eat the operator pair
            if(op->type_id()==TKN_L_PAREN || op->type_id()==TKN_L_SQUARE)
                ConsumeToken();

            ScopeBlock Operator;
            Operator.name = *op;
            m_Context.nameQueue.push_back(Operator);
            Token *peek = PeekToken();
            if(peek->type_id()==TKN_L_PAREN)
            {
                HandleFunction();
            }
            break;
        }
        default:
        {
            //cout<<"Skip unhandled"<<*tk<<endl;
            // As the tk is only a pointer to the Token buffer, so it may changed by
            // some function calling on ConsumeToken or PeekToken
            ConsumeToken();
            break;
        }
        }
    }

}
Exemplo n.º 4
0
BriefParser::BriefParser(Lexer &L) : L(L)
{
  // Get lookahead token.
  ConsumeToken();
}