1 //===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This class implements the parser for assembly files.
12 //===----------------------------------------------------------------------===//
14 #include "AsmParser.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCInst.h"
17 #include "llvm/MC/MCStreamer.h"
18 #include "llvm/Support/SourceMgr.h"
19 #include "llvm/Support/raw_ostream.h"
22 bool AsmParser::Error(SMLoc L, const char *Msg) {
23 Lexer.PrintMessage(L, Msg);
27 bool AsmParser::TokError(const char *Msg) {
28 Lexer.PrintMessage(Lexer.getLoc(), Msg);
32 bool AsmParser::Run() {
36 while (Lexer.isNot(asmtok::Eof))
43 /// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
44 void AsmParser::EatToEndOfStatement() {
45 while (Lexer.isNot(asmtok::EndOfStatement) &&
46 Lexer.isNot(asmtok::Eof))
50 if (Lexer.is(asmtok::EndOfStatement))
55 /// ParseParenExpr - Parse a paren expression and return it.
56 /// NOTE: This assumes the leading '(' has already been consumed.
58 /// parenexpr ::= expr)
60 bool AsmParser::ParseParenExpr(int64_t &Res) {
61 if (ParseExpression(Res)) return true;
62 if (Lexer.isNot(asmtok::RParen))
63 return TokError("expected ')' in parentheses expression");
68 /// ParsePrimaryExpr - Parse a primary expression and return it.
69 /// primaryexpr ::= (parenexpr
70 /// primaryexpr ::= symbol
71 /// primaryexpr ::= number
72 /// primaryexpr ::= ~,+,- primaryexpr
73 bool AsmParser::ParsePrimaryExpr(int64_t &Res) {
74 switch (Lexer.getKind()) {
76 return TokError("unknown token in expression");
77 case asmtok::Identifier:
78 // This is a label, this should be parsed as part of an expression, to
79 // handle things like LFOO+4
81 Lexer.Lex(); // Eat identifier.
84 Res = Lexer.getCurIntVal();
85 Lexer.Lex(); // Eat identifier.
88 Lexer.Lex(); // Eat the '('.
89 return ParseParenExpr(Res);
93 Lexer.Lex(); // Eat the operator.
94 return ParsePrimaryExpr(Res);
98 /// ParseExpression - Parse an expression and return it.
100 /// expr ::= expr +,- expr -> lowest.
101 /// expr ::= expr |,^,&,! expr -> middle.
102 /// expr ::= expr *,/,%,<<,>> expr -> highest.
103 /// expr ::= primaryexpr
105 bool AsmParser::ParseExpression(int64_t &Res) {
106 return ParsePrimaryExpr(Res) ||
107 ParseBinOpRHS(1, Res);
110 static unsigned getBinOpPrecedence(asmtok::TokKind K) {
112 default: return 0; // not a binop.
119 case asmtok::Exclaim:
123 case asmtok::Percent:
124 case asmtok::LessLess:
125 case asmtok::GreaterGreater:
131 /// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
132 /// Res contains the LHS of the expression on input.
133 bool AsmParser::ParseBinOpRHS(unsigned Precedence, int64_t &Res) {
135 unsigned TokPrec = getBinOpPrecedence(Lexer.getKind());
137 // If the next token is lower precedence than we are allowed to eat, return
138 // successfully with what we ate already.
139 if (TokPrec < Precedence)
142 //asmtok::TokKind BinOp = Lexer.getKind();
145 // Eat the next primary expression.
147 if (ParsePrimaryExpr(RHS)) return true;
149 // If BinOp binds less tightly with RHS than the operator after RHS, let
150 // the pending operator take RHS as its LHS.
151 unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind());
152 if (TokPrec < NextTokPrec) {
153 if (ParseBinOpRHS(Precedence+1, RHS)) return true;
156 // Merge LHS/RHS: fixme use the right operator etc.
165 /// ::= EndOfStatement
166 /// ::= Label* Directive ...Operands... EndOfStatement
167 /// ::= Label* Identifier OperandList* EndOfStatement
168 bool AsmParser::ParseStatement() {
169 switch (Lexer.getKind()) {
171 return TokError("unexpected token at start of statement");
172 case asmtok::EndOfStatement:
175 case asmtok::Identifier:
177 // TODO: Recurse on local labels etc.
180 // If we have an identifier, handle it as the key symbol.
181 SMLoc IDLoc = Lexer.getLoc();
182 const char *IDVal = Lexer.getCurStrVal();
184 // Consume the identifier, see what is after it.
185 if (Lexer.Lex() == asmtok::Colon) {
186 // identifier ':' -> Label.
188 return ParseStatement();
191 // Otherwise, we have a normal instruction or directive.
192 if (IDVal[0] == '.') {
193 Lexer.PrintMessage(IDLoc, "warning: ignoring directive for now");
194 EatToEndOfStatement();
200 if (ParseX86InstOperands(Inst))
203 if (Lexer.isNot(asmtok::EndOfStatement))
204 return TokError("unexpected token in operand list");
206 // Eat the end of statement marker.
209 // Instruction is good, process it.
210 outs() << "Found instruction: " << IDVal << " with " << Inst.getNumOperands()
213 // Skip to end of line for now.