コード例 #1
0
void Resource::Comment()
{
	Match(';');

	while (!Is('\n') && !Is(EOF))
	{
		Lex();
	}

	if (Is(';'))
	{
		Comment();
	}
}
コード例 #2
0
ファイル: ParseExpr.cpp プロジェクト: ctgriffiths/flang
Parser::ExprResult Parser::ParseEquivOperand() {
  ExprResult E = ParseOrOperand();
  if (E.isInvalid()) return E;

  while (Tok.getKind() == tok::kw_OR) {
    SourceLocation OpLoc = Tok.getLocation();
    Lex();
    ExprResult OrOp = ParseOrOperand();
    if (OrOp.isInvalid()) return OrOp;
    E = Actions.ActOnBinaryExpr(Context, OpLoc, BinaryExpr::Or, E, OrOp);
  }

  return E;
}
コード例 #3
0
ファイル: ParseExpr.cpp プロジェクト: ctgriffiths/flang
Parser::ExprResult Parser::ParseLevel5Expr() {
  ExprResult E = ParseEquivOperand();
  if (E.isInvalid()) return E;

  while (true) {
    SourceLocation OpLoc = Tok.getLocation();
    switch (Tok.getKind()) {
    default:
      return E;
    case tok::kw_EQV:
      Lex();
      E = Actions.ActOnBinaryExpr(Context, OpLoc, BinaryExpr::Eqv, E,
                               ParseEquivOperand());
      break;
    case tok::kw_NEQV:
      Lex();
      E = Actions.ActOnBinaryExpr(Context, OpLoc, BinaryExpr::Neqv, E,
                               ParseEquivOperand());
      break;
    }
  }
  return E;
}
コード例 #4
0
ファイル: ParseExpr.cpp プロジェクト: ctgriffiths/flang
Parser::ExprResult Parser::ParseOrOperand() {
  ExprResult E = ParseAndOperand();
  if (E.isInvalid()) return E;

  while (Tok.getKind() == tok::kw_AND) {
    SourceLocation OpLoc = Tok.getLocation();
    Lex();
    ExprResult AndOp = ParseAndOperand();
    if (AndOp.isInvalid()) return AndOp;
    E = Actions.ActOnBinaryExpr(Context, OpLoc, BinaryExpr::And, E, AndOp);
  }

  return E;
}
コード例 #5
0
ファイル: ParseExpr.cpp プロジェクト: ctgriffiths/flang
// ParseLevel3Expr - Level-3 expressions are level-2 expressions optionally
// involving the character operator concat-op.
//
//   R710:
//     level-3-expr :=
//         [ level-3-expr concat-op ] level-2-expr
//   R711:
//     concat-op :=
//         //
Parser::ExprResult Parser::ParseLevel3Expr() {
  ExprResult E = ParseLevel2Expr();
  if (E.isInvalid()) return E;

  while (Tok.getKind() == tok::slashslash) {
    SourceLocation OpLoc = Tok.getLocation();
    Lex();
    ExprResult Lvl2Expr = ParseLevel2Expr();
    if (Lvl2Expr.isInvalid()) return Lvl2Expr;
    E = Actions.ActOnBinaryExpr(Context, OpLoc, BinaryExpr::Concat, E, Lvl2Expr);
  }
  
  return E;
}
コード例 #6
0
ファイル: ParseExpr.cpp プロジェクト: ctgriffiths/flang
// ParseLevel2Expr - Level-2 expressions are level-1 expressions optionally
// involving the numeric operators power-op, mult-op, and add-op.
//
//   R706:
//     level-2-expr :=
//         [ [ level-2-expr ] add-op ] add-operand
//   R705:
//     add-operand :=
//         [ add-operand mult-op ] mult-operand
//   R704:
//     mult-operand :=
//         level-1-expr [ power-op mult-operand ]
//   R707:
//     power-op :=
//         **
//   R708:
//     mult-op :=
//         *
//      or /
//   R709:
//     add-op :=
//         +
//      or -
Parser::ExprResult Parser::ParseMultOperand() {
  ExprResult E = ParseLevel1Expr();
  if (E.isInvalid()) return E;

  if (Tok.getKind() == tok::starstar) {
    SourceLocation OpLoc = Tok.getLocation();
    Lex();
    ExprResult MulOp = ParseMultOperand();
    if (MulOp.isInvalid()) return MulOp;
    E = Actions.ActOnBinaryExpr(Context, OpLoc, BinaryExpr::Power, E, MulOp);
  }

  return E;
}
コード例 #7
0
F64 CompileDemo(U8 *st)
{
  I64 type;
  U8 *ex;
  CLex *lx=LexNew(st,LF_DONT_FREE_BUF);
  F64 result=0;
  Lex(lx);  //Gotta get it started
  "Compile \"%s\"\n",st;
  do {
    if (ex=LexExpression2Bin(lx,&type)) {
      if (type!=IT_F64)
	result=ToF64(Call(ex));
      else
	result=Call(ex)(F64);
      ExpressionBinDel(ex);
    }
    "result=%9.4f\n",result;
    if (lx->token==';')
      Lex(lx);
  } while (lx->token!=TK_EOF);	//end of file?
  LexDel(lx);
  return result;
}
コード例 #8
0
bool Resource::Match(char c)
{
  bool r = Is(c);


  if (!r)
  {
    Expected(c);
  }

  Lex();

  return r;
}
コード例 #9
0
ファイル: lexer.cpp プロジェクト: artyrian/university
bool Scanner:: state_DELIM (int c)
{
    int i;

    if ( (i = look (buffer->get (), table->delim)) != 0 ) {
        CS = H;
        save_c = c;
        save_lex = Lex (count_str, table->lex_delim [i], i);
        return true;
    }
    else {
        printf ("%dbuf[%s]\n", i, buffer->get ());
        throw SymbolException ( "Not found delim (state DELIM).", c, count_str);
    }
}
コード例 #10
0
ファイル: lexer.cpp プロジェクト: artyrian/university
bool Scanner:: state_LABEL (int c)
{
    if ( isalpha (c) || isdigit (c) || ( c == '_') ) {
        buffer->add (c);
        return false;
    }
    else {
        int i = table->label.put (buffer->get ());
        CS = H;
        save_c = c;

        save_lex = Lex (count_str, LEX_LABEL, i);
        return true;
    }

}
コード例 #11
0
ファイル: ParseExpr.cpp プロジェクト: ctgriffiths/flang
// ParseExpression - Expressions are level-5 expressions optionally involving
// defined binary operators.
//
//   R722:
//     expr :=
//         [ expr defined-binary-op ] level-5-expr
//
//   R723:
//     defined-binary-op :=
//         . letter [ letter ] ... .
Parser::ExprResult Parser::ParseExpression() {
  ExprResult LHS = ParseLevel5Expr();
  if (LHS.isInvalid()) return LHS;

  if (!IsPresent(tok::defined_operator))
    return LHS;

  SourceLocation OpLoc = Tok.getLocation();
  IdentifierInfo *II = Tok.getIdentifierInfo();
  Lex();

  ExprResult RHS = ParseLevel5Expr();
  if (RHS.isInvalid()) return RHS;

  return DefinedBinaryOperatorExpr::Create(Context, OpLoc, LHS.take(), RHS.take(), II);
}
コード例 #12
0
ファイル: ParseExpr.cpp プロジェクト: ctgriffiths/flang
// ParseLevel1Expr - Level-1 expressions are primaries optionally operated on by
// defined unary operators.
//
//   R702:
//     level-1-expr :=
//         [ defined-unary-op ] primary
//   R703:
//     defined-unary-op :=
//         . letter [ letter ] ... .
Parser::ExprResult Parser::ParseLevel1Expr() {
  SourceLocation OpLoc = Tok.getLocation();
  IdentifierInfo *II = 0;
 if (IsPresent(tok::defined_operator) && !IsNextToken(tok::l_paren)) {
    II = Tok.getIdentifierInfo();
    Lex();
  }

  ExprResult E = ParsePrimaryExpr();
  if (E.isInvalid()) return E;

  if (II)
    E = DefinedUnaryOperatorExpr::Create(Context, OpLoc, E.take(), II);

  return E;
}
コード例 #13
0
 std::string format(llvm::StringRef Code, unsigned Offset, unsigned Length,
                    const FormatStyle &Style) {
   RewriterTestContext Context;
   FileID ID = Context.createInMemoryFile("input.cc", Code);
   SourceLocation Start =
       Context.Sources.getLocForStartOfFile(ID).getLocWithOffset(Offset);
   std::vector<CharSourceRange> Ranges(
       1,
       CharSourceRange::getCharRange(Start, Start.getLocWithOffset(Length)));
   LangOptions LangOpts;
   LangOpts.CPlusPlus = 1;
   Lexer Lex(ID, Context.Sources.getBuffer(ID), Context.Sources, LangOpts);
   tooling::Replacements Replace =
       reformat(Style, Lex, Context.Sources, Ranges);
   EXPECT_TRUE(applyAllReplacements(Replace, Context.Rewrite));
   return Context.getRewrittenText(ID);
 }
コード例 #14
0
ファイル: lexer.cpp プロジェクト: artyrian/university
bool Scanner:: state_LEG (int c)
{
    int i;
    if ( look (c, table->compare) != 0 ) {
        buffer->add (c);
        return false;
    }
    else if ( (i = look (buffer->get (), table->compare)) != 0 ) {
        CS = H;
        save_c = c;
        save_lex = Lex (count_str, table->lex_compare [i], i);
        return true;
    }
    else {
        printf ("%dbuf[%s]\n", i, buffer->get ());
        throw SymbolException ( "Not found delim (state LEG).", c, count_str);
    }
}
コード例 #15
0
ファイル: expr.cpp プロジェクト: DanLipsitt/solvespace
Expr *Expr::From(const char *in, bool popUpError) {
    UnparsedCnt = 0;
    UnparsedP = 0;
    OperandsP = 0;
    OperatorsP = 0;

    Expr *r;
    try {
        Lex(in);
        Parse();
        r = PopOperand();
    } catch (const char *e) {
        dbp("exception: parse/lex error: %s", e);
        if(popUpError) {
            Error("Not a valid number or expression: '%s'", in);
        }
        return NULL;
    }
    return r;
}
コード例 #16
0
// Looks for the token matching the predicate and returns the range of the found
// token including trailing whitespace.
static SourceRange FindToken(const SourceManager &Sources, LangOptions LangOpts,
                             SourceLocation StartLoc, SourceLocation EndLoc,
                             bool (*Pred)(const Token &)) {
  if (StartLoc.isMacroID() || EndLoc.isMacroID())
    return SourceRange();
  FileID File = Sources.getFileID(Sources.getSpellingLoc(StartLoc));
  StringRef Buf = Sources.getBufferData(File);
  const char *StartChar = Sources.getCharacterData(StartLoc);
  Lexer Lex(StartLoc, LangOpts, StartChar, StartChar, Buf.end());
  Lex.SetCommentRetentionState(true);
  Token Tok;
  do {
    Lex.LexFromRawLexer(Tok);
    if (Pred(Tok)) {
      Token NextTok;
      Lex.LexFromRawLexer(NextTok);
      return SourceRange(Tok.getLocation(), NextTok.getLocation());
    }
  } while (Tok.isNot(tok::eof) && Tok.getLocation() < EndLoc);

  return SourceRange();
}
コード例 #17
0
ファイル: lexer.cpp プロジェクト: artyrian/university
bool Scanner:: state_FN (int c)
{
    if ( isalpha (c) || isdigit (c) || (c == '_') ) {
        buffer->add (c);
        //
        return false;
    }
    else {
        int i;
        if ( (i = look (buffer->get (), table->function)) != 0 ) {
            CS = H;
            save_c = c;

            save_lex = Lex (count_str, table->lex_function [i], i);
            return true;
        }
        else {
            perror ("Not found function.\n");
            throw SymbolException ("Not found function.", c, count_str);
        }
    }
}
コード例 #18
0
ファイル: ParseExpr.cpp プロジェクト: ctgriffiths/flang
// ParseLevel4Expr - Level-4 expressions are level-3 expressions optionally
// involving the relational operators.
//
//   R712:
//     level-4-expr :=
//         [ level-3-expr rel-op ] level-3-expr
//   R713:
//     rel-op :=
//         .EQ.
//      or .NE.
//      or .LT.
//      or .LE.
//      or .GT.
//      or .GE.
//      or ==
//      or /=
//      or <
//      or <=
//      or >
//      or >=
Parser::ExprResult Parser::ParseLevel4Expr() {
  ExprResult E = ParseLevel3Expr();
  if (E.isInvalid()) return E;

  while (true) {
    SourceLocation OpLoc = Tok.getLocation();
    BinaryExpr::Operator Op = BinaryExpr::None;
    switch (Tok.getKind()) {
    default:
      return E;
    case tok::kw_EQ: case tok::equalequal:
      Op = BinaryExpr::Equal;
      break;
    case tok::kw_NE: case tok::slashequal:
      Op = BinaryExpr::NotEqual;
      break;
    case tok::kw_LT: case tok::less:
      Op = BinaryExpr::LessThan;
      break;
    case tok::kw_LE: case tok::lessequal:
      Op = BinaryExpr::LessThanEqual;
      break;
    case tok::kw_GT: case tok::greater:
      Op = BinaryExpr::GreaterThan;
      break;
    case tok::kw_GE: case tok::greaterequal:
      Op = BinaryExpr::GreaterThanEqual;
      break;
    }

    Lex();
    ExprResult Lvl3Expr = ParseLevel3Expr();
    if (Lvl3Expr.isInvalid()) return Lvl3Expr;
    E = Actions.ActOnBinaryExpr(Context, OpLoc, Op, E, Lvl3Expr);
  }
  return E;
}
コード例 #19
0
CQueVectU8 *EdRICode(CDoc *doc)
{
  CQueVectU8 *result;
  CRILex *rx=CAlloc(sizeof(CRILex));

  rx->lx1=LexNew(NULL,LF_KEEP_NEW_LINES|LF_DONT_FREE_BUF,doc->filename.name);
  Free(rx->lx1->lfns[0].name);
  LexAttachDoc(rx->lx1,&rx->lx1->lfns[0],doc,,doc->cur_entry,doc->cur_data_col);

  rx->lx2=LexNew(NULL,LF_KEEP_NEW_LINES|LF_DONT_FREE_BUF,doc->filename.name);
  Free(rx->lx2->lfns[0].name);
  LexAttachDoc(rx->lx2,&rx->lx2->lfns[0],doc,,doc->cur_entry,doc->cur_data_col);

  rx->indent=QueVectU8New(doc->cur_entry->y);

  Lex(rx->lx1);
  EdRIStmt(rx,FALSE);

  LexDel(rx->lx1);
  LexDel(rx->lx2);
  result=rx->indent;
  Free(rx);
  return result;
}
コード例 #20
0
ファイル: ClangFormat.cpp プロジェクト: zygoloid/clang
// Returns true on error.
static bool format(std::string FileName) {
  FileManager Files((FileSystemOptions()));
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
      new DiagnosticOptions);
  SourceManager Sources(Diagnostics, Files);
  OwningPtr<MemoryBuffer> Code;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
    llvm::errs() << ec.message() << "\n";
    return true;
  }
  FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
  Lexer Lex(ID, Sources.getBuffer(ID), Sources, getFormattingLangOpts());
  if (Offsets.empty())
    Offsets.push_back(0);
  if (Offsets.size() != Lengths.size() &&
      !(Offsets.size() == 1 && Lengths.empty())) {
    llvm::errs()
        << "error: number of -offset and -length arguments must match.\n";
    return true;
  }
  std::vector<CharSourceRange> Ranges;
  for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
    if (Offsets[i] >= Code->getBufferSize()) {
      llvm::errs() << "error: offset " << Offsets[i]
                   << " is outside the file\n";
      return true;
    }
    SourceLocation Start =
        Sources.getLocForStartOfFile(ID).getLocWithOffset(Offsets[i]);
    SourceLocation End;
    if (i < Lengths.size()) {
      if (Offsets[i] + Lengths[i] > Code->getBufferSize()) {
        llvm::errs() << "error: invalid length " << Lengths[i]
                     << ", offset + length (" << Offsets[i] + Lengths[i]
                     << ") is outside the file.\n";
        return true;
      }
      End = Start.getLocWithOffset(Lengths[i]);
    } else {
      End = Sources.getLocForEndOfFile(ID);
    }
    Ranges.push_back(CharSourceRange::getCharRange(Start, End));
  }
  tooling::Replacements Replaces = reformat(getStyle(), Lex, Sources, Ranges);
  if (OutputXML) {
    llvm::outs()
        << "<?xml version='1.0'?>\n<replacements xml:space='preserve'>\n";
    for (tooling::Replacements::const_iterator I = Replaces.begin(),
                                               E = Replaces.end();
         I != E; ++I) {
      llvm::outs() << "<replacement "
                   << "offset='" << I->getOffset() << "' "
                   << "length='" << I->getLength() << "'>"
                   << I->getReplacementText() << "</replacement>\n";
    }
    llvm::outs() << "</replacements>\n";
  } else {
    Rewriter Rewrite(Sources, LangOptions());
    tooling::applyAllReplacements(Replaces, Rewrite);
    if (Inplace) {
      if (Replaces.size() == 0)
        return false; // Nothing changed, don't touch the file.

      std::string ErrorInfo;
      llvm::raw_fd_ostream FileStream(FileName.c_str(), ErrorInfo,
                                      llvm::raw_fd_ostream::F_Binary);
      if (!ErrorInfo.empty()) {
        llvm::errs() << "Error while writing file: " << ErrorInfo << "\n";
        return true;
      }
      Rewrite.getEditBuffer(ID).write(FileStream);
      FileStream.flush();
    } else {
      Rewrite.getEditBuffer(ID).write(outs());
    }
  }
  return false;
}
コード例 #21
0
clang::NamedDecl *parseDeclarationReference(llvm::StringRef Text, clang::Sema &Sema, bool isFunction) {

    clang::Preprocessor &PP = Sema.getPreprocessor();

    llvm::MemoryBuffer* Buf = llvm::MemoryBuffer::getMemBufferCopy(Text);
#if CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR <= 4
    auto FID = PP.getSourceManager().createFileIDForMemBuffer(Buf);
#else
    auto FID = PP.getSourceManager().createFileID(Buf);
#endif
    clang::Lexer Lex(FID, Buf, PP.getSourceManager(), PP.getLangOpts());

    auto TuDecl = Sema.getASTContext().getTranslationUnitDecl();
    clang::CXXScopeSpec SS;
    clang::Token Tok, Next;
    Lex.LexFromRawLexer(Tok);

    for (; !Tok.is(clang::tok::eof); Tok = Next) {
        Lex.LexFromRawLexer(Next);
        clang::IdentifierInfo* II = nullptr;
        if (Tok.is(clang::tok::raw_identifier)) {
            II = PP.LookUpIdentifierInfo(Tok);
        }

        if (Tok.is(clang::tok::coloncolon)) {
            SS.MakeGlobal(Sema.getASTContext(), Tok.getLocation());
            continue;
        } else if (Tok.is(clang::tok::identifier)) {

            if (Next.is(clang::tok::coloncolon)) {

                clang::Sema::TemplateTy Template;
                clang::UnqualifiedId Name;
                Name.setIdentifier(II, Tok.getLocation());
                bool dummy;
                auto TemplateKind = Sema.isTemplateName(Sema.getScopeForContext(TuDecl), SS, false, Name, {}, false, Template, dummy);
                if (TemplateKind == clang::TNK_Non_template) {
                    if (Sema.ActOnCXXNestedNameSpecifier(Sema.getScopeForContext(TuDecl), *II, Tok.getLocation(), Next.getLocation(), {}, false, SS))
                        SS.SetInvalid(Tok.getLocation());
                } else if (auto T = Template.get().getAsTemplateDecl()) {
                    // FIXME: For template, it is a bit tricky
                    // It is still a bit broken but works in some cases for most normal functions
                    auto T2 = llvm::dyn_cast_or_null<clang::CXXRecordDecl>(T->getTemplatedDecl());
                    if (T2) {
                        Lex.LexFromRawLexer(Tok);
                        if (!Tok.is(clang::tok::raw_identifier))
                            return nullptr;
                        II = PP.LookUpIdentifierInfo(Tok);
                        Lex.LexFromRawLexer(Next);
                        if (!Next.is(clang::tok::eof) && !Next.is(clang::tok::l_paren))
                            return nullptr;
                        auto Result = T2->lookup(II);
                        if (Result.size() != 1)
                            return nullptr;
                        auto D = Result.front();
                        if (isFunction && (llvm::isa<clang::RecordDecl>(D)
                                    || llvm::isa<clang::ClassTemplateDecl>(D))) {
                            // TODO constructor
                            return nullptr;
                        }
                        return D;
                    }
                }
                Lex.LexFromRawLexer(Next);
                continue;
            }

            if (Next.is(clang::tok::eof) || Next.is(clang::tok::l_paren)) {
                clang::LookupResult Found(Sema, II, Tok.getLocation(), clang::Sema::LookupOrdinaryName);
                Found.suppressDiagnostics();

                if (SS.isEmpty())
                    Sema.LookupQualifiedName(Found, TuDecl);
                else {
                    clang::DeclContext* DC = Sema.computeDeclContext(SS);
                    Sema.LookupQualifiedName(Found, DC ? DC : TuDecl);
                }


                if (Found.isSingleResult()) {
                    auto Decl = Found.getFoundDecl();
                    if (isFunction && (llvm::isa<clang::RecordDecl>(Decl)
                                       || llvm::isa<clang::ClassTemplateDecl>(Decl))) {
                        // TODO handle constructors.
                        return nullptr;
                    }
                    return Decl;
                }

                if (Found.isOverloadedResult() && Next.is(clang::tok::l_paren)) {
                    // TODO
                }
                return nullptr;
            }
        }
        if (Tok.is(clang::tok::tilde) || Tok.is(clang::tok::kw_operator)) {
            //TODO
            return nullptr;
        }

        if (!isFunction)
            return nullptr;
        SS = {};
        // Then it is probably the return type, just skip it.
    }
    return nullptr;
}
コード例 #22
0
ファイル: ParseExpr.cpp プロジェクト: ctgriffiths/flang
// ParsePrimaryExpr - Parse a primary expression.
//
//   [R701]:
//     primary :=
//         constant
//      or designator
//      or array-constructor
//      or structure-constructor
//      or function-reference
//      or type-param-inquiry
//      or type-param-name
//      or ( expr )
Parser::ExprResult Parser::ParsePrimaryExpr(bool IsLvalue) {
  ExprResult E;
  SourceLocation Loc = Tok.getLocation();

  // FIXME: Add rest of the primary expressions.
  switch (Tok.getKind()) {
  default:
    if (isTokenIdentifier())
      goto possible_keyword_as_ident;
    Diag.Report(getExpectedLoc(), diag::err_expected_expression);
    return ExprError();
  case tok::error:
    Lex();
    return ExprError();
  case tok::l_paren: {
    ConsumeParen();

    E = ParseExpression();
    // complex constant.
    if(ConsumeIfPresent(tok::comma)) {
      if(E.isInvalid()) return E;
      auto ImPart = ParseExpectedFollowupExpression(",");
      if(ImPart.isInvalid()) return ImPart;
      E = Actions.ActOnComplexConstantExpr(Context, Loc,
                                           getMaxLocationOfCurrentToken(),
                                           E, ImPart);
    }

    ExpectAndConsume(tok::r_paren, 0, "", tok::r_paren);
    break;
  }
  case tok::l_parenslash : {
    return ParseArrayConstructor();
    break;
  }
  case tok::logical_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = LogicalConstantExpr::Create(Context, getTokenRange(),
                                    StrPair.first, Context.LogicalTy);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);
    ConsumeToken();
    break;
  }
  case tok::binary_boz_constant:
  case tok::octal_boz_constant:
  case tok::hex_boz_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = BOZConstantExpr::Create(Context, Loc,
                                getMaxLocationOfCurrentToken(),
                                StrPair.first);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);
    ConsumeToken();
    break;
  }
  case tok::char_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);
    E = CharacterConstantExpr::Create(Context, getTokenRange(),
                                      StringRef(NumStr), Context.CharacterTy);
    ConsumeToken();
    // Possible substring
    if(IsPresent(tok::l_paren))
      return ParseSubstring(E);
    break;
  }
  case tok::int_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = IntegerConstantExpr::Create(Context, getTokenRange(),
                                    StrPair.first);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);

    Lex();
    break;
  }
  case tok::real_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = RealConstantExpr::Create(Context, getTokenRange(),
                                 NumStr, Context.RealTy);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);
    ConsumeToken();
    break;
  }
  case tok::double_precision_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);
    // Replace the d/D exponent into e exponent
    for(size_t I = 0, Len = NumStr.length(); I < Len; ++I) {
      if(NumStr[I] == 'd' || NumStr[I] == 'D') {
        NumStr[I] = 'e';
        break;
      } else if(NumStr[I] == '_') break;
    }

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = RealConstantExpr::Create(Context, getTokenRange(),
                                 NumStr, Context.DoublePrecisionTy);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);
    ConsumeToken();
    break;
  }
  case tok::identifier:
    possible_keyword_as_ident:
    E = Parser::ParseDesignator(IsLvalue);
    if (E.isInvalid()) return E;
    break;
  case tok::minus:
    Lex();
    E = Parser::ParsePrimaryExpr();
    if (E.isInvalid()) return E;
    E = Actions.ActOnUnaryExpr(Context, Loc, UnaryExpr::Minus, E);
    break;
  case tok::plus:
    Lex();
    E = Parser::ParsePrimaryExpr();
    if (E.isInvalid()) return E;
    E = Actions.ActOnUnaryExpr(Context, Loc, UnaryExpr::Plus, E);
    break;
  }

  return E;
}
コード例 #23
0
void Preprocessor::RecursivePreprocess( std::string filename, FileLoader& file_source, LexemList& lexems, DefineTable& define_table )
{
    unsigned int start_line = CurrentLine;
    LinesThisFile = 0;
    CurrentFile = filename;
    SetFileMacro( define_table, CurrentFile );
    SetLineMacro( define_table, LinesThisFile );

    // Path formatting must be done in main application
    std::string CurrentFileRoot = RootPath + CurrentFile;
    if( std::find( FilesPreprocessed.begin(), FilesPreprocessed.end(), CurrentFileRoot ) == FilesPreprocessed.end() )
        FilesPreprocessed.push_back( CurrentFileRoot );

    std::vector<char> data;
    bool              loaded = file_source.LoadFile( RootPath, filename, data );
    if( !loaded )
    {
        PrintErrorMessage( std::string( "Could not open file " ) + RootPath + filename );
        return;
    }

    if( data.size() == 0 )
        return;
    char* d_end = &data[data.size() - 1];
    ++d_end;
    Lex( &data[0], d_end, lexems );

    LexemList::iterator itr = lexems.begin();
    LexemList::iterator end = lexems.end();
    LLITR               old = end;
    while( itr != end )
    {
        if( itr->Type == Lexem::NEWLINE )
        {
            if( itr != old )
            {
                CurrentLine++;
                LinesThisFile++;
                SetLineMacro( define_table, LinesThisFile );
            }
            old = itr;
            ++itr;
        }
        else if( itr->Type == Lexem::PREPROCESSOR )
        {
            LLITR     start_of_line = itr;
            LLITR     end_of_line = ParsePreprocessor( lexems, itr, end );

            LexemList directive( start_of_line, end_of_line );

            if( SkipPragmas && directive.begin()->Value == "#pragma" )
            {
                itr = end_of_line;
                Lexem wspace;
                wspace.Type = Lexem::WHITESPACE;
                wspace.Value = " ";
                for( LLITR it = start_of_line; it != end_of_line;)
                {
                    ++it;
                    it = lexems.insert( it, wspace );
                    ++it;
                }
                continue;
            }

            itr = lexems.erase( start_of_line, end_of_line );

            std::string value = directive.begin()->Value;
            if( value == "#define" )
            {
                ParseDefine( define_table, directive );
            }
            else if( value == "#ifdef" )
            {
                std::string           def_name;
                ParseIf( directive, def_name );
                DefineTable::iterator dti = define_table.find( def_name );
                if( dti == define_table.end() )
                {
                    LLITR splice_to = ParseIfDef( itr, end );
                    itr = lexems.erase( itr, splice_to );
                }
            }
            else if( value == "#ifndef" )
            {
                std::string           def_name;
                ParseIf( directive, def_name );
                DefineTable::iterator dti = define_table.find( def_name );
                if( dti != define_table.end() )
                {
                    LLITR splice_to = ParseIfDef( itr, end );
                    itr = lexems.erase( itr, splice_to );
                }
            }
            else if( value == "#if" )
            {
                bool satisfied = EvaluateExpression( define_table, directive ) != 0;
                if( !satisfied )
                {
                    LLITR splice_to = ParseIfDef( itr, end );
                    itr = lexems.erase( itr, splice_to );
                }
            }
            else if( value == "#endif" )
            {
                // ignore
            }
            else if( value == "#include" )
            {
                if( LNT )
                    LNT->AddLineRange( PrependRootPath( filename ), start_line, CurrentLine - LinesThisFile );
                unsigned int save_lines_this_file = LinesThisFile;
                std::string  file_name;
                ParseIf( directive, file_name );

                std::string file_name_ = RemoveQuotes( file_name );
                if( IncludeTranslator )
                    IncludeTranslator->Call( file_name_ );
                if( std::find( FileDependencies.begin(), FileDependencies.end(), file_name_ ) == FileDependencies.end() )
                    FileDependencies.push_back( file_name_ );

                LexemList next_file;
                RecursivePreprocess( AddPaths( filename, file_name_ ), file_source, next_file, define_table );
                lexems.splice( itr, next_file );
                start_line = CurrentLine;
                LinesThisFile = save_lines_this_file;
                CurrentFile = filename;
                SetFileMacro( define_table, CurrentFile );
                SetLineMacro( define_table, LinesThisFile );
            }
            else if( value == "#pragma" )
            {
                ParsePragma( directive );
            }
            else if( value == "#message" )
            {
                std::string message;
                ParseTextLine( directive, message );
                PrintMessage( message );
            }
            else if( value == "#warning" )
            {
                std::string warning;
                ParseTextLine( directive, warning );
                PrintWarningMessage( warning );
            }
            else if( value == "#error" )
            {
                std::string error;
                ParseTextLine( directive, error );
                PrintErrorMessage( error );
            }
            else
            {
                PrintErrorMessage( "Unknown directive '" + value + "'." );
            }
        }
        else if( itr->Type == Lexem::IDENTIFIER )
        {
            itr = ExpandDefine( itr, end, lexems, define_table );
        }
        else
        {
            ++itr;
        }
    }

    if( LNT )
        LNT->AddLineRange( PrependRootPath( filename ), start_line, CurrentLine - LinesThisFile );
}
コード例 #24
0
ファイル: mocng.cpp プロジェクト: gmrehbein/moc-ng
static void parsePluginMetaData(ClassDef &Def, clang::Expr *Content, clang::Sema &Sema) {
    clang::Preprocessor &PP = Sema.getPreprocessor();
    clang::StringLiteral *Val = llvm::dyn_cast<clang::StringLiteral>(Content);
    if (!Val) {
        PP.getDiagnostics().Report(Content->getExprLoc(),
                                   PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error,
                                                                       "Invalid Q_PLUGIN_METADATA annotation"));
        return;
    }

    llvm::MemoryBuffer* Buf = maybe_unique(llvm::MemoryBuffer::getMemBufferCopy(Val->getString(), "Q_PLUGIN_METADATA"));
    clang::Lexer Lex(CreateFileIDForMemBuffer(PP, Buf, Content->getExprLoc()),
                     Buf, PP.getSourceManager(), PP.getLangOpts());

    clang::Token Tok;
    Lex.LexFromRawLexer(Tok);
    while (Tok.is(clang::tok::raw_identifier)) {
        clang::IdentifierInfo *II =  PP.LookUpIdentifierInfo(Tok);
        if (II->getName() != "IID" && II->getName() != "FILE") {
            Lex.LexFromRawLexer(Tok);
            continue;
        }

        Lex.LexFromRawLexer(Tok);
        if (!Tok.is(clang::tok::string_literal)) {
            PP.getDiagnostics().Report(GetFromLiteral(Tok, Val, PP),
                        PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error,
                                                            "Expected string literal"));
            return;
        }

        llvm::SmallVector<clang::Token, 4> StrToks;
        do {
            StrToks.push_back(Tok);
            Lex.LexFromRawLexer(Tok);
        } while (Tok.is(clang::tok::string_literal));
#if CLANG_VERSION_MAJOR!=3 || CLANG_VERSION_MINOR>4
        clang::StringLiteralParser Literal(StrToks, PP);
#else
        clang::StringLiteralParser Literal(&StrToks[0], StrToks.size(), PP);
#endif
        if (Literal.hadError)
            return;

        if (II->getName() == "IID")
            Def.Plugin.IID = Literal.GetString();
        else {
            llvm::StringRef Filename = Literal.GetString();
            const clang::DirectoryLookup *CurDir;
            const clang::FileEntry *File = PP.LookupFile(
#if CLANG_VERSION_MAJOR!=3 || CLANG_VERSION_MINOR>3
                Val->getLocStart(),
#endif
                Filename, false, nullptr,
#if CLANG_VERSION_MAJOR!=3 || CLANG_VERSION_MINOR>5
                nullptr,
#endif
                CurDir, nullptr, nullptr, nullptr);

            if (!File) {
                PP.getDiagnostics().Report(GetFromLiteral(StrToks.front(), Val, PP), clang::diag::err_pp_file_not_found)
                    << Filename;
                return;
            }
            const llvm::MemoryBuffer* JSonBuf = PP.getSourceManager().getMemoryBufferForFile(File);
            llvm::SourceMgr SM;
            llvm::yaml::Stream YAMLStream(JSonBuf->getBuffer(), SM);
            llvm::yaml::document_iterator I = YAMLStream.begin();
            if (I == YAMLStream.end() || !I->getRoot() || !QBJS::Parse(I->getRoot(), Def.Plugin.MetaData)) {
                // FIXME
                PP.getDiagnostics().Report(GetFromLiteral(Tok, Val, PP),
                                            PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error,
                                            "Error pwhile parsing JSON"));
                return;
            }
        }
     }

     if (!Tok.is(clang::tok::eof)) {
         PP.getDiagnostics().Report(GetFromLiteral(Tok, Val, PP),
                                    PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error,
                                                                        "Parse error: Expected 'IID' or 'FILE'"));
         return;
     }

}
コード例 #25
0
ファイル: mocng.cpp プロジェクト: gmrehbein/moc-ng
static void parseEnums(ClassDef &Def, bool isFlag, clang::Expr *Content, clang::Sema &Sema) {
    clang::Preprocessor &PP = Sema.getPreprocessor();
    clang::StringLiteral *Val = llvm::dyn_cast<clang::StringLiteral>(Content);
    if (!Val) {
        PP.getDiagnostics().Report(Content->getExprLoc(),
                                   PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error,
                                   "Invalid Q_ENUMS annotation"));
        return;
    }

    llvm::MemoryBuffer* Buf = maybe_unique(llvm::MemoryBuffer::getMemBufferCopy(Val->getString(), "Q_ENUMS"));
    clang::Lexer Lex(CreateFileIDForMemBuffer(PP, Buf, Content->getExprLoc()),
                     Buf, PP.getSourceManager(), PP.getLangOpts());

    clang::CXXScopeSpec SS;
    clang::Token Tok, Next;
    Lex.LexFromRawLexer(Tok);
    for (; !Tok.is(clang::tok::eof); Tok = Next) {
        Lex.LexFromRawLexer(Next);
        clang::IdentifierInfo* II = nullptr;
        if (Tok.is(clang::tok::raw_identifier))
            II = PP.LookUpIdentifierInfo(Tok);


        if (Tok.is(clang::tok::identifier)) {

            if (Next.is(clang::tok::coloncolon)) {
                if (Sema.ActOnCXXNestedNameSpecifier(Sema.getScopeForContext(Def.Record), *II,
                        GetFromLiteral(Tok, Val, PP), GetFromLiteral(Next, Val, PP), {}, false, SS))
                    SS.SetInvalid({GetFromLiteral(Tok, Val, PP), GetFromLiteral(Next, Val, PP)});

                Lex.LexFromRawLexer(Next);
                continue;
            }

            clang::LookupResult Found(Sema, II, GetFromLiteral(Tok, Val, PP), clang::Sema::LookupNestedNameSpecifierName);
            if (SS.isEmpty())
                Sema.LookupQualifiedName(Found, Def.Record);
            else {
                clang::DeclContext* DC = Sema.computeDeclContext(SS);
                Sema.LookupQualifiedName(Found, DC ? DC : Def.Record);
            }

            llvm::StringRef Alias;
            clang::EnumDecl* R = Found.getAsSingle<clang::EnumDecl>();

            if (!R) {
                if (clang::TypedefDecl *TD = Found.getAsSingle<clang::TypedefDecl>()) {
                    const clang::EnumType* ET = TD->getUnderlyingType()->getAs<clang::EnumType>();
                    const clang::TemplateSpecializationType* TDR = TD->getUnderlyingType()->getAs<clang::TemplateSpecializationType>();
                    if(TDR && TDR->getNumArgs() == 1 && TDR->getTemplateName().getAsTemplateDecl()->getName() == "QFlags")
                        ET = TDR->getArg(0).getAsType()->getAs<clang::EnumType>();
                    if (ET) {
                        R = ET->getDecl();
                        if (TD->getIdentifier())
                            Alias = TD->getName();
                    }
                }
            }

            if (Found.empty() || !R) {
                // TODO: typo correction

                // This should be an error, but the official moc do not understand that as an error.
                PP.getDiagnostics().Report(GetFromLiteral(Tok, Val, PP),
                                           PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Warning,
                                            "no enum names %0")) << Found.getLookupName();
                break;
            }
            if (R->getDeclContext() == Def.Record) {
                if (Alias.empty() && R->getIdentifier())
                    Alias = R->getName();
                Def.addEnum(R, Alias.empty() ? R->getNameAsString() : std::string(Alias), isFlag);
            } else if (R->getDeclContext()->isRecord() &&  llvm::isa<clang::CXXRecordDecl>(R->getDeclContext())) {
                // TODO: check it is a QObject
                Def.addExtra(llvm::cast<clang::CXXRecordDecl>(R->getDeclContext()));
            }
            SS.clear();
            continue;
        } else if (Tok.is(clang::tok::coloncolon)) {
            if (SS.isEmpty()) {
                SS.MakeGlobal(Sema.getASTContext(), GetFromLiteral(Tok, Val, PP));
                continue;
            }
        }

        PP.getDiagnostics().Report(GetFromLiteral(Tok, Val, PP),
                                       PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error,
                                       "Invalid token in Q_ENUMS"));
        break;
    }


}
コード例 #26
0
arg_list_t *Resource::Symbol()
{
  int i = 0, j;
  arg_list_t *a;
  bool string = false;
  bool fp = false;
  float f;
  arg_list_t *adt;


  _symbol[0] = 0;

  if (Is('"'))
  {
	  Lex();
	  string = true;
  }

  // Mongoose 2001.11.09: Best handle for? grouped (func (func
  if (Is('('))
  {
	  return Function(arg_peek(&_stack));
  }

  while (string || (i == 0 && _look == '-') ||
			isatoz(_look) || isAtoZ(_look) || isdigit(_look) || ismisc(_look))
  {
	  if (i < (int)_symbol_len)
	  {
		  _symbol[i++] = _look;
		  _symbol[i] = 0;
	  }

	  if (string && Is('"'))
	  {
		  i--;
		  _symbol[i] = 0;
		  Lex();
		  break;
	  }
    
	  Lex();

	  if (string)
	  {
		  continue;
	  }

	  if (Is('.'))
	  {
		  fp = true;

		  for (j = 0; j < i; j++)
		  {
			  if (!j && _symbol[j] == '-')
				  continue;

			  if (!isdigit(_symbol[j]))
				  break;
		  }

		  if (i == j)
		  {
			  _symbol[i++] = _look;
			  _symbol[i] = 0;
			  Lex();
		  }
	  }


	  // Mongoose 2002.01.23, Hhhmm... fixes -100.00 and -100, 
	  //   but is it 'good idea'?
	  if (Is('-') && i == 0)
	  {
		  _symbol[i++] = _look;
		  _symbol[i] = 0;
		  Lex();
	  }
  }

#ifdef DEBUG_RESOURCE_SYMBOL
  printf("%s\n", _symbol);
#endif

  if (isnumeric(_symbol, &f))
  {
	  if (fp)
	  {
		  new_float(&a, f);
	  }
	  else
	  {
		  new_int(&a, (int)f);
	  }
  }
  else
  {
	  // Mongoose 2002.01.21, FIXME support ADTs and etc too
	  if (Lookup(_symbol, &i))
	  {
		  new_int(&a, i);
	  }
	  else if (Lookup(_symbol, &f))
	  {
		  new_float(&a, f);
	  }
	  else if (string)
	  {
		  mlisp_new_string(&a, _symbol);
	  }
	  else if (Lookup(_symbol, &adt))
	  {
		  mlisp_new_adt(&a, adt->type, adt->data);
	  }
	  else
	  {
		  // Mongoose 2002.01.21, FIXME: hack to handle old string
		  //   use for def symbols
		  mlisp_new_string(&a, _symbol);
	  }
  }

  return a;
}
コード例 #27
0
int Resource::Eval(char *buffer)
{
	arg_list_t *a, *b, *c;


	if (!buffer || !buffer[0])
	{
		return -1;
	}

	// Mongoose: Start counting lines at 1, errors at 0
	_line = 1; 
	_error = 0;


#ifdef MULTI_EVAL
	_top = 0;
	_string = 0;

	while (_stack)
	{
		arg_pop(&_stack);
	}

	_stack = NULL;
#endif

	Lex();
	Seperator();

	while (Is('#'))
	{
		printf("Resource::Eval> Preprocessor not implemented yet.\n");
		
		Lex();
		a = Symbol();
		Seperator();
		b = Symbol();
		Seperator();
		c = Symbol();
		Seperator();

		// #func arg1 arg2  ( eg #define FOOBAR 1 )

		// Preprocessor function
		delete_arg(&a);

		// Arg 1
		delete_arg(&b);

		// Arg 2
		delete_arg(&c);
	}

	a = NULL;

	while (Is('('))
	{
		// FIXME: Handle scope with paren counter and appending to list a
		a = Function(a);
		Seperator();
	}
			
	if (_error)
		printf("\n\nEval> Encountered %i Errors\n\n", _error);

	return 0;
}
コード例 #28
0
Lex Scanner::get_lex() {
    int d = 0, j, n = 1;
    double r = 0;
    CS = H;
    do {
        switch (CS) {
            case H:
                if (c == ' ' || c == '\n' || c == '\r' || c == '\t')
                    gc();
                else if (isalpha(c)) {
                    clear();
                    add();
                    gc();
                    CS = IDENT;
                    //cout << "H IDENT" << endl;
                }
                else if (isdigit(c)) {
                    d = c - '0';
                    gc();
                    CS = NUM;
                    //cout << "H NUM" << endl;
                }
                else if (c == '{') {
                    gc();
                    CS = COM;
                    //cout << "H COM" << endl;
                }
                else if (c == ':' || c == '<' || c == '>') {
                    clear();
                    add();
                    gc();
                    CS = ALE;
                    //cout << "H ALE" << endl;
                }
                else if (c == '@') {
                    //cout << "H return" << endl;
                    return Lex(LEX_FIN);
                }
                else if (c == '!') {
                    clear();
                    add();
                    gc();
                    CS = NEQ;
                    //cout << "H NEQ" << endl;
                }
                else if (c == '&') {
                    clear();
                    add();
                    gc();
                    CS = UNMINUS;
                    //cout << "H NEQ" << endl;
                }
                else {
                    CS = DELIM;
                    //cout << "H DELIM" << endl;
                }
                break;
            case IDENT:
                if (isalpha(c) || isdigit(c)) {
                    //cout << "IDENT here1" << endl;
                    add();
                    gc();
                }
                else if (j = look(buf, TW)) {
                    //cout << "IDENT here2" << endl;
                    cout << "buf " << buf << endl;
                    return Lex(words[j], j);
                }
                else {
                    //cout << "IDENT here3" << endl;
                    //cout << "buf " << buf << endl;
                    j = TID.put(buf);
                    return Lex(LEX_ID, j);
                }
                break;
            case NUM:
                if (isdigit(c)) {
                    d = d * 10 + (c - '0');
                    gc();
                }
                else if (c == '.') {
                    gc();
                    CS = REAL;
                }
                else
                    return Lex(LEX_NUM, d);
                break;
            case REAL:
                if (isdigit(c)) {
                    r = r * 10 + (c - '0');
                    n *= 10;
                    gc();
                }
                else
                    return Lex(LEX_NUM, d + r / n);
                break;
            case COM:
                if (c == '}') {
                    gc();
                    CS = H;
                }
                else if (c == '@' || c == '{')
                    throw c;
                else {
                    gc();
                }
                break;
            case ALE:
                if (c == '=') {
                    add();
                    gc();
                    j = look(buf, TD);
                    cout << "buf " << buf << endl;
                    return Lex(dlms[j], j);
                }
                else {
                    j = look(buf, TD);
                    return Lex(dlms[j], j);
                }
                break;
            case NEQ:
                if (c == '=') {
                    add();
                    gc();
                    j = look(buf, TD);
                    return Lex(LEX_NEQ, j);
                }
                else
                    throw '!';
                break;
            case UNMINUS:
                j = look(buf, TD);
                return Lex(LEX_UN_MINUS, j);
                break;
            case DELIM:
                clear();
                add();
                if (j = look(buf, TD)) {
                    gc();
                    return Lex(dlms[j], j);
                }
                else
                    throw c;
                break;
        } // end switch
    } while (true);

}
コード例 #29
0
  InputValidator::ValidationResult
  InputValidator::validate(llvm::StringRef line) {
    ValidationResult Res = kComplete;

    Token Tok;
    const char* curPos = line.data();
    bool multilineComment = inBlockComment();
    int commentTok = multilineComment ? tok::asterik : tok::slash;

    if (!multilineComment && m_ParenStack.empty()) {
      // Only check for 'template' if we're not already indented
      MetaLexer Lex(curPos, true);
      Lex.Lex(Tok);
      curPos = Lex.getLocation();
      if (Tok.is(tok::ident)) {
        if (Tok.getIdent()=="template")
          m_ParenStack.push_back(tok::greater);
      } else
        curPos -= Tok.getLength(); // Rewind buffer for LexPunctuatorAndAdvance
    }

    do {
      const char* prevStart = curPos;
      if (!MetaLexer::LexPunctuatorAndAdvance(curPos, Tok)) {
        // there were tokens between the previous and this Tok.
        commentTok = tok::slash;
      }
      const int kind = (int)Tok.getKind();

      if (kind == commentTok) {
        if (kind == tok::slash) {
          if (multilineComment) {
            // exiting a comment, unwind the stack
            multilineComment = false;
            commentTok = tok::slash;
            unwindTokens(m_ParenStack, tok::slash);
          }
          // If we have a closing comment without a start it will be transformed
          // to */; and clang reports an error for both the */ and the ;
          // If we return kIncomplete, then just one error is printed, but too
          // late: after the user has another expression which will always fail.
          // So just deal with two errors for now
          // else if (prevKind == tok::asterik) {
          //  Res = kIncomplete;
          // break;
          // }
          else   // wait for an asterik
            commentTok = tok::asterik;
        }
        else {
          assert(commentTok == tok::asterik && "Comment token not / or *");
          if (!multilineComment) {
            // entering a new comment
            multilineComment = true;
            m_ParenStack.push_back(tok::slash);
          }
          else // wait for closing / (must be next token)
            commentTok = tok::slash;
        }
      }
      else {
        // If we're in a multiline, and waiting for the closing slash
        // we gonna have to wait for another asterik first
        if (multilineComment) {
          if (kind == tok::eof) {
            switch (findNestedBlockComments(prevStart, curPos)) {
              case -1: unwindTokens(m_ParenStack, tok::slash);
              case  1:
              case  0: break;
              default: assert(0 && "Nested block comment count"); break;
            }
            // eof, were done anyway
            break;
          }
          else if (commentTok == tok::slash) {
            // Cancel the wait for a slash, but only if current token isn't
            // also an asterik.
            if (kind != tok::asterik)
              commentTok = tok::asterik;
          }
        }

        if (kind >= (int)tok::l_square && kind <= (int)tok::r_brace) {
          // The closing paren kind is open paren kind + 1 (i.e odd number)
          if (kind % 2) {
            int prev = m_ParenStack.empty() ? -1: m_ParenStack.back();
            // closing the right one?
            if (prev != kind - 1) {
              if (multilineComment)
                continue;
              Res = kMismatch;
              break;
            }
            m_ParenStack.pop_back();

            // Right brace will pop a template if their is one
            if (kind == tok::r_brace && m_ParenStack.size() == 1 ) {
              if (m_ParenStack.back() == tok::greater)
                m_ParenStack.pop_back();
            }
          }
          else
            m_ParenStack.push_back(kind);
        }
        else if (kind == tok::hash) {
          MetaLexer Lex(curPos);
          Lex.SkipWhitespace();
          Lex.LexAnyString(Tok);
          const llvm::StringRef PPtk = Tok.getIdent();
          if (PPtk.startswith("endif")
              && (PPtk.size() > 5 ? PPtk[5]=='/' || isspace(PPtk[5]) : true)) {
            if (m_ParenStack.empty() || m_ParenStack.back() != tok::hash) {
              Res = kMismatch;
              break;
            }
            m_ParenStack.pop_back();
          }
          else if (PPtk.startswith("if")) {
            m_ParenStack.push_back(tok::hash);
          }
        }
        else if (kind == tok::semicolon) {
          // Template forward declatation
          if (m_ParenStack.size() == 1 && m_ParenStack.back()==tok::greater)
            m_ParenStack.pop_back();
        }
        else if (kind >= (int)tok::stringlit && kind <= (int)tok::charlit) {
          MetaLexer::LexQuotedStringAndAdvance(curPos, Tok);
        }
      }
    } while (Tok.isNot(tok::eof));

    if (!m_ParenStack.empty() && Res != kMismatch)
      Res = kIncomplete;

    if (!m_Input.empty()) {
      if (!m_ParenStack.empty() && (m_ParenStack.back() == tok::stringlit
                                    || m_ParenStack.back() == tok::charlit))
        m_Input.append("\\n");
      else
        m_Input.append("\n");
    }
    else
      m_Input = "";

    m_Input.append(line);

    return Res;
  }
コード例 #30
0
/// ParseTypeDeclarationStmt - Parse a type-declaration-stmt construct.
///
///   [R501]:
///     type-declaration-stmt :=
///         declaration-type-spec [ [ , attr-spec ] ... :: ] entity-decl-list
bool Parser::ParseTypeDeclarationStmt(SmallVectorImpl<DeclResult> &Decls) {
  DeclSpec DS;
  if (ParseDeclarationTypeSpec(DS))
    return true;

  while (ConsumeIfPresent(tok::comma)) {
    // [R502]:
    //   attr-spec :=
    //       access-spec
    //    or ALLOCATABLE
    //    or ASYNCHRONOUS
    //    or CODIMENSION lbracket coarray-spec rbracket
    //    or CONTIGUOUS
    //    or DIMENSION ( array-spec )
    //    or EXTERNAL
    //    or INTENT ( intent-spec )
    //    or INTRINSIC
    //    or language-binding-spec // TODO!
    //    or OPTIONAL
    //    or PARAMETER
    //    or POINTER
    //    or PROTECTED
    //    or SAVE
    //    or TARGET
    //    or VALUE
    //    or VOLATILE
    auto Kind = Tok.getKind();
    auto Loc = Tok.getLocation();
    if(!ExpectAndConsume(tok::identifier)) {
      goto error;
    }
    switch (Kind) {
    default:
      Diag.ReportError(Loc,
                       "unknown attribute specification");
      goto error;
    case tok::kw_ALLOCATABLE:
      Actions.ActOnAttrSpec(Loc, DS, DeclSpec::AS_allocatable);
      break;
    case tok::kw_ASYNCHRONOUS:
      Actions.ActOnAttrSpec(Loc, DS, DeclSpec::AS_asynchronous);
      break;
    case tok::kw_CODIMENSION:
      Actions.ActOnAttrSpec(Loc, DS, DeclSpec::AS_codimension);
      // FIXME: Parse the coarray-spec.
      break;
    case tok::kw_CONTIGUOUS:
      Actions.ActOnAttrSpec(Loc, DS, DeclSpec::AS_contiguous);
      break;
    case tok::kw_DIMENSION:
      if (ParseDimensionAttributeSpec(Loc, DS))
        goto error;
      break;
    case tok::kw_EXTERNAL:
      Actions.ActOnAttrSpec(Loc, DS, DeclSpec::AS_external);
      break;
    case tok::kw_INTENT:
      // FIXME:
      if(!ExpectAndConsume(tok::l_paren))
        goto error;

      switch (Tok.getKind()) {
      default:
        Diag.ReportError(Tok.getLocation(),
                         "invalid INTENT specifier");
        goto error;
      case tok::kw_IN:
        Actions.ActOnIntentSpec(Loc, DS, DeclSpec::IS_in);
        break;
      case tok::kw_OUT:
        Actions.ActOnIntentSpec(Loc, DS, DeclSpec::IS_out);
        break;
      case tok::kw_INOUT:
        Actions.ActOnIntentSpec(Loc, DS, DeclSpec::IS_inout);
        break;
      }
      Lex();

      if(!ExpectAndConsume(tok::r_paren))
        goto error;

      break;
    case tok::kw_INTRINSIC:
      Actions.ActOnAttrSpec(Loc, DS, DeclSpec::AS_intrinsic);
      break;
    case tok::kw_OPTIONAL:
      Actions.ActOnAttrSpec(Loc, DS, DeclSpec::AS_optional);
      break;
    case tok::kw_PARAMETER:
      Actions.ActOnAttrSpec(Loc, DS, DeclSpec::AS_parameter);
      break;
    case tok::kw_POINTER:
      Actions.ActOnAttrSpec(Loc, DS, DeclSpec::AS_pointer);
      break;
    case tok::kw_PROTECTED:
      Actions.ActOnAttrSpec(Loc, DS, DeclSpec::AS_protected);
      break;
    case tok::kw_SAVE:
      Actions.ActOnAttrSpec(Loc, DS, DeclSpec::AS_save);
      break;
    case tok::kw_TARGET:
      Actions.ActOnAttrSpec(Loc, DS, DeclSpec::AS_target);
      break;
    case tok::kw_VALUE:
      Actions.ActOnAttrSpec(Loc, DS, DeclSpec::AS_value);
      break;
    case tok::kw_VOLATILE:
      Actions.ActOnAttrSpec(Loc, DS, DeclSpec::AS_volatile);
      break;

    // Access Control Specifiers
    case tok::kw_PUBLIC:
      Actions.ActOnAccessSpec(Loc, DS, DeclSpec::AC_public);
      break;
    case tok::kw_PRIVATE:
      Actions.ActOnAccessSpec(Loc, DS, DeclSpec::AC_private);
      break;
    }
  }

  ConsumeIfPresent(tok::coloncolon);

  if (ParseEntityDeclarationList(DS, Decls))
    return true;

  return false;
 error:
  return true;
}