From: Chris Lattner Date: Tue, 23 Jun 2009 05:57:07 +0000 (+0000) Subject: implement a trivial binary expression parser, we can now parse all of 176.gcc.llc.s X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=8dfbe6c853e3e48b6e7b5957a4e028835ffe4400;p=oota-llvm.git implement a trivial binary expression parser, we can now parse all of 176.gcc.llc.s git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73950 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/tools/llvm-mc/AsmLexer.cpp b/tools/llvm-mc/AsmLexer.cpp index 95937d2a606..dbd3c06db77 100644 --- a/tools/llvm-mc/AsmLexer.cpp +++ b/tools/llvm-mc/AsmLexer.cpp @@ -75,17 +75,18 @@ asmtok::TokKind AsmLexer::LexIdentifier() { while (isalnum(*CurPtr) || *CurPtr == '_' || *CurPtr == '$' || *CurPtr == '.' || *CurPtr == '@') ++CurPtr; - CurStrVal.assign(TokStart, CurPtr); // Include % + CurStrVal.assign(TokStart, CurPtr); return asmtok::Identifier; } /// LexPercent: Register: %[a-zA-Z0-9]+ asmtok::TokKind AsmLexer::LexPercent() { if (!isalnum(*CurPtr)) - return ReturnError(TokStart, "invalid register name"); + return asmtok::Percent; // Single %. + while (isalnum(*CurPtr)) ++CurPtr; - CurStrVal.assign(TokStart, CurPtr); // Skip % + CurStrVal.assign(TokStart, CurPtr); // Include % return asmtok::Register; } @@ -243,6 +244,10 @@ asmtok::TokKind AsmLexer::LexToken() { case '*': return asmtok::Star; case ',': return asmtok::Comma; case '$': return asmtok::Dollar; + case '|': return asmtok::Pipe; + case '^': return asmtok::Caret; + case '&': return asmtok::Amp; + case '!': return asmtok::Exclaim; case '%': return LexPercent(); case '/': return LexSlash(); case '#': return LexHash(); @@ -250,6 +255,20 @@ asmtok::TokKind AsmLexer::LexToken() { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return LexDigit(); + case '<': + if (*CurPtr == '<') { + ++CurPtr; + return asmtok::LessLess; + } + // Don't have any use for bare '<' yet. + return ReturnError(TokStart, "invalid character in input"); + case '>': + if (*CurPtr == '>') { + ++CurPtr; + return asmtok::GreaterGreater; + } + // Don't have any use for bare '>' yet. + return ReturnError(TokStart, "invalid character in input"); // TODO: Quoted identifiers (objc methods etc) // local labels: [0-9][:] diff --git a/tools/llvm-mc/AsmLexer.h b/tools/llvm-mc/AsmLexer.h index a6c93230c6c..23c5f851bc0 100644 --- a/tools/llvm-mc/AsmLexer.h +++ b/tools/llvm-mc/AsmLexer.h @@ -42,7 +42,10 @@ namespace asmtok { Plus, Minus, Tilde, Slash, // '/' LParen, RParen, - Star, Comma, Dollar + Star, Comma, Dollar, + + Pipe, Caret, Amp, Exclaim, + Percent, LessLess, GreaterGreater }; } diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp index 715ff3932bc..9e8b3cf2eff 100644 --- a/tools/llvm-mc/AsmParser.cpp +++ b/tools/llvm-mc/AsmParser.cpp @@ -168,7 +168,9 @@ bool AsmParser::ParseX86MemOperand(X86Operand &Op) { // memory operand consumed. } else { // It must be an parenthesized expression, parse it now. - if (ParseParenExpr(Disp)) return true; + if (ParseParenExpr(Disp) || + ParseBinOpRHS(1, Disp)) + return true; // After parsing the base expression we could either have a parenthesized // memory address or not. If not, return now. If so, eat the (. @@ -274,9 +276,61 @@ bool AsmParser::ParsePrimaryExpr(int64_t &Res) { /// expr ::= primaryexpr /// bool AsmParser::ParseExpression(int64_t &Res) { - return ParsePrimaryExpr(Res); + return ParsePrimaryExpr(Res) || + ParseBinOpRHS(1, Res); } - + +static unsigned getBinOpPrecedence(asmtok::TokKind K) { + switch (K) { + default: return 0; // not a binop. + case asmtok::Plus: + case asmtok::Minus: + return 1; + case asmtok::Pipe: + case asmtok::Caret: + case asmtok::Amp: + case asmtok::Exclaim: + return 2; + case asmtok::Star: + case asmtok::Slash: + case asmtok::Percent: + case asmtok::LessLess: + case asmtok::GreaterGreater: + return 3; + } +} + + +/// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'. +/// Res contains the LHS of the expression on input. +bool AsmParser::ParseBinOpRHS(unsigned Precedence, int64_t &Res) { + while (1) { + unsigned TokPrec = getBinOpPrecedence(Lexer.getKind()); + + // If the next token is lower precedence than we are allowed to eat, return + // successfully with what we ate already. + if (TokPrec < Precedence) + return false; + + //asmtok::TokKind BinOp = Lexer.getKind(); + Lexer.Lex(); + + // Eat the next primary expression. + int64_t RHS; + if (ParsePrimaryExpr(RHS)) return true; + + // If BinOp binds less tightly with RHS than the operator after RHS, let + // the pending operator take RHS as its LHS. + unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind()); + if (TokPrec < NextTokPrec) { + if (ParseBinOpRHS(Precedence+1, RHS)) return true; + } + + // Merge LHS/RHS: fixme use the right operator etc. + Res += RHS; + } +} + diff --git a/tools/llvm-mc/AsmParser.h b/tools/llvm-mc/AsmParser.h index 82eb433b61e..1dadb40ce2b 100644 --- a/tools/llvm-mc/AsmParser.h +++ b/tools/llvm-mc/AsmParser.h @@ -40,6 +40,7 @@ private: bool ParseX86MemOperand(X86Operand &Op); bool ParseExpression(int64_t &Res); bool ParsePrimaryExpr(int64_t &Res); + bool ParseBinOpRHS(unsigned Precedence, int64_t &Res); bool ParseParenExpr(int64_t &Res); };