//===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class implements the parser for assembly files.
//
//===----------------------------------------------------------------------===//
#include "AsmParser.h"
#include "AsmExpr.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
void AsmParser::Warning(SMLoc L, const char *Msg) {
Lexer.PrintMessage(L, Msg, "warning");
}
bool AsmParser::Error(SMLoc L, const char *Msg) {
Lexer.PrintMessage(L, Msg, "error");
return true;
}
bool AsmParser::TokError(const char *Msg) {
Lexer.PrintMessage(Lexer.getLoc(), Msg, "error");
return true;
}
bool AsmParser::Run() {
// Prime the lexer.
Lexer.Lex();
bool HadError = false;
// While we have input, parse each statement.
while (Lexer.isNot(asmtok::Eof)) {
if (!ParseStatement()) continue;
// If we had an error, remember it and recover by skipping to the next line.
HadError = true;
EatToEndOfStatement();
}
return HadError;
}
/// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
void AsmParser::EatToEndOfStatement() {
while (Lexer.isNot(asmtok::EndOfStatement) &&
Lexer.isNot(asmtok::Eof))
Lexer.Lex();
// Eat EOL.
if (Lexer.is(asmtok::EndOfStatement))
Lexer.Lex();
}
/// ParseParenExpr - Parse a paren expression and return it.
/// NOTE: This assumes the leading '(' has already been consumed.
///
/// parenexpr ::= expr)
///
bool AsmParser::ParseParenExpr(AsmExpr *&Res) {
if (ParseExpression(Res)) return true;
if (Lexer.isNot(asmtok::RParen))
return TokError("expected ')' in parentheses expression");
Lexer.Lex();
return false;
}
/// ParsePrimaryExpr - Parse a primary expression and return it.
/// primaryexpr ::= (parenexpr
/// primaryexpr ::= symbol
/// primaryexpr ::= number
/// primaryexpr ::= ~,+,- primaryexpr
bool AsmParser::ParsePrimaryExpr(AsmExpr *&Res) {
switch (Lexer.getKind()) {
default:
return TokError("unknown token in expression");
case asmtok::Exclaim:
Lexer.Lex(); // Eat the operator.
if (ParsePrimaryExpr(Res))
return true;
Res = new AsmUnaryExpr(AsmUnaryExpr::LNot, Res);
return false;
case asmtok::Identifier: {
// This is a label, this should be parsed as part of an expression, to
// handle things like LFOO+4.
MCSymbol *Sym = Ctx.GetOrCreateSymbol(Lexer.getCurStrVal());
// If this is use of an undefined symbol then mark it external.
if (!Sym->getSection() && !