00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "expr/Parser.h"
00011
00012 #include "expr/Lexer.h"
00013
00014 #include "klee/Constraints.h"
00015 #include "klee/Solver.h"
00016 #include "klee/util/ExprPPrinter.h"
00017
00018 #include "llvm/ADT/APInt.h"
00019 #include "llvm/Support/MemoryBuffer.h"
00020 #include "llvm/Support/Streams.h"
00021
00022 #include <cassert>
00023 #include <iostream>
00024 #include <map>
00025 #include <cstring>
00026
00027 using namespace llvm;
00028 using namespace klee;
00029 using namespace klee::expr;
00030
00031 namespace {
00033 template<typename T>
00034 struct ParseResult {
00035 bool IsValid;
00036 T Value;
00037
00038 public:
00039 ParseResult() : IsValid(false) {}
00040 ParseResult(T _Value) : IsValid(true), Value(_Value) {}
00041 ParseResult(bool _IsValid, T _Value) : IsValid(_IsValid), Value(_Value) {}
00042
00043 bool isValid() {
00044 return IsValid;
00045 }
00046 T get() {
00047 assert(IsValid && "get() on invalid ParseResult!");
00048 return Value;
00049 }
00050 };
00051
00052 class ExprResult {
00053 bool IsValid;
00054 ExprHandle Value;
00055
00056 public:
00057 ExprResult() : IsValid(false) {}
00058 ExprResult(ExprHandle _Value) : IsValid(true), Value(_Value) {}
00059 ExprResult(ref<ConstantExpr> _Value) : IsValid(true), Value(_Value.get()) {}
00060 ExprResult(bool _IsValid, ExprHandle _Value) : IsValid(_IsValid), Value(_Value) {}
00061
00062 bool isValid() {
00063 return IsValid;
00064 }
00065 ExprHandle get() {
00066 assert(IsValid && "get() on invalid ParseResult!");
00067 return Value;
00068 }
00069 };
00070
00071 typedef ParseResult<Decl*> DeclResult;
00072 typedef ParseResult<Expr::Width> TypeResult;
00073 typedef ParseResult<VersionHandle> VersionResult;
00074
00078 class NumberOrExprResult {
00079 Token AsNumber;
00080 ExprResult AsExpr;
00081 bool IsNumber;
00082
00083 public:
00084 NumberOrExprResult() : IsNumber(false) {}
00085 explicit NumberOrExprResult(Token _AsNumber) : AsNumber(_AsNumber),
00086 IsNumber(true) {}
00087 explicit NumberOrExprResult(ExprResult _AsExpr) : AsExpr(_AsExpr),
00088 IsNumber(false) {}
00089
00090 bool isNumber() const { return IsNumber; }
00091 const Token &getNumber() const {
00092 assert(IsNumber && "Invalid accessor call.");
00093 return AsNumber;
00094 }
00095 const ExprResult &getExpr() const {
00096 assert(!IsNumber && "Invalid accessor call.");
00097 return AsExpr;
00098 }
00099 };
00100
00102 class ParserImpl : public Parser {
00103 typedef std::map<const std::string, const Identifier*> IdentifierTabTy;
00104 typedef std::map<const Identifier*, ExprHandle> ExprSymTabTy;
00105 typedef std::map<const Identifier*, VersionHandle> VersionSymTabTy;
00106
00107 const std::string Filename;
00108 const MemoryBuffer *TheMemoryBuffer;
00109 Lexer TheLexer;
00110 unsigned MaxErrors;
00111 unsigned NumErrors;
00112
00113
00114 IdentifierTabTy IdentifierTab;
00115
00116 std::map<const Identifier*, const ArrayDecl*> ArraySymTab;
00117 ExprSymTabTy ExprSymTab;
00118 VersionSymTabTy VersionSymTab;
00119
00121 Token Tok;
00122
00124 unsigned ParenLevel;
00126 unsigned SquareLevel;
00127
00128
00129
00130 const Identifier *GetOrCreateIdentifier(const Token &Tok);
00131
00132 void GetNextNonCommentToken() {
00133 do {
00134 TheLexer.Lex(Tok);
00135 } while (Tok.kind == Token::Comment);
00136 }
00137
00139 void ConsumeToken() {
00140 assert(Tok.kind != Token::LParen && Tok.kind != Token::RParen);
00141 GetNextNonCommentToken();
00142 }
00143
00146 void ConsumeExpectedToken(Token::Kind k) {
00147 assert(Tok.kind == k && "Unexpected token!");
00148 GetNextNonCommentToken();
00149 }
00150
00151 void ConsumeLParen() {
00152 ++ParenLevel;
00153 ConsumeExpectedToken(Token::LParen);
00154 }
00155
00156 void ConsumeRParen() {
00157 if (ParenLevel)
00158 --ParenLevel;
00159 ConsumeExpectedToken(Token::RParen);
00160 }
00161
00162 void ConsumeLSquare() {
00163 ++SquareLevel;
00164 ConsumeExpectedToken(Token::LSquare);
00165 }
00166
00167 void ConsumeRSquare() {
00168 if (SquareLevel)
00169 --SquareLevel;
00170 ConsumeExpectedToken(Token::RSquare);
00171 }
00172
00173 void ConsumeAnyToken() {
00174 switch (Tok.kind) {
00175 case Token::LParen: return ConsumeLParen();
00176 case Token::RParen: return ConsumeRParen();
00177 case Token::LSquare: return ConsumeLSquare();
00178 case Token::RSquare: return ConsumeRSquare();
00179 default:
00180 return ConsumeToken();
00181 }
00182 }
00183
00184
00185
00188 void SkipUntilRParen(unsigned Level) {
00189
00190
00191
00192
00193 assert(Level <= ParenLevel &&
00194 "Refusing to skip until rparen at higher level.");
00195 while (Tok.kind != Token::EndOfFile) {
00196 if (Tok.kind == Token::RParen && ParenLevel == Level) {
00197 ConsumeRParen();
00198 break;
00199 }
00200 ConsumeAnyToken();
00201 }
00202 }
00203
00206 void SkipUntilRParen() {
00207 SkipUntilRParen(ParenLevel);
00208 }
00209
00213 void ExpectRParen(const char *Msg) {
00214 if (Tok.kind == Token::EndOfFile) {
00215
00216 Error("expected ')' but found end-of-file.", Tok);
00217 } else if (Tok.kind != Token::RParen) {
00218 Error(Msg, Tok);
00219 SkipUntilRParen();
00220 } else {
00221 ConsumeRParen();
00222 }
00223 }
00224
00227 void SkipUntilRSquare(unsigned Level) {
00228
00229
00230
00231
00232 assert(Level <= ParenLevel &&
00233 "Refusing to skip until rparen at higher level.");
00234 while (Tok.kind != Token::EndOfFile) {
00235 if (Tok.kind == Token::RSquare && ParenLevel == Level) {
00236 ConsumeRSquare();
00237 break;
00238 }
00239 ConsumeAnyToken();
00240 }
00241 }
00242
00245 void SkipUntilRSquare() {
00246 SkipUntilRSquare(ParenLevel);
00247 }
00248
00252 void ExpectRSquare(const char *Msg) {
00253 if (Tok.kind == Token::EndOfFile) {
00254
00255 Error("expected ']' but found end-of-file.", Tok);
00256 } else if (Tok.kind != Token::RSquare) {
00257 Error(Msg, Tok);
00258 SkipUntilRSquare();
00259 } else {
00260 ConsumeRSquare();
00261 }
00262 }
00263
00264
00265
00266
00267
00268 DeclResult ParseArrayDecl();
00269 DeclResult ParseExprVarDecl();
00270 DeclResult ParseVersionVarDecl();
00271 DeclResult ParseCommandDecl();
00272
00273
00274
00275 DeclResult ParseQueryCommand();
00276
00277
00278
00279 NumberOrExprResult ParseNumberOrExpr();
00280
00281 ExprResult ParseExpr(TypeResult ExpectedType);
00282 ExprResult ParseParenExpr(TypeResult ExpectedType);
00283 ExprResult ParseUnaryParenExpr(const Token &Name,
00284 unsigned Kind, bool IsFixed,
00285 Expr::Width ResTy);
00286 ExprResult ParseBinaryParenExpr(const Token &Name,
00287 unsigned Kind, bool IsFixed,
00288 Expr::Width ResTy);
00289 ExprResult ParseSelectParenExpr(const Token &Name, Expr::Width ResTy);
00290 ExprResult ParseConcatParenExpr(const Token &Name, Expr::Width ResTy);
00291 ExprResult ParseExtractParenExpr(const Token &Name, Expr::Width ResTy);
00292 ExprResult ParseAnyReadParenExpr(const Token &Name,
00293 unsigned Kind,
00294 Expr::Width ResTy);
00295 void ParseMatchedBinaryArgs(const Token &Name,
00296 TypeResult ExpectType,
00297 ExprResult &LHS, ExprResult &RHS);
00298 ExprResult ParseNumber(Expr::Width Width);
00299 ExprResult ParseNumberToken(Expr::Width Width, const Token &Tok);
00300
00301 VersionResult ParseVersionSpecifier();
00302 VersionResult ParseVersion();
00303
00304 TypeResult ParseTypeSpecifier();
00305
00306
00307
00308 void Error(const char *Message, const Token &At);
00309 void Error(const char *Message) { Error(Message, Tok); }
00310
00311 public:
00312 ParserImpl(const std::string _Filename,
00313 const MemoryBuffer *MB) : Filename(_Filename),
00314 TheMemoryBuffer(MB),
00315 TheLexer(MB),
00316 MaxErrors(~0u),
00317 NumErrors(0) {}
00318
00321 void Initialize() {
00322 ParenLevel = SquareLevel = 0;
00323
00324 ConsumeAnyToken();
00325 }
00326
00327
00328
00329 virtual Decl *ParseTopLevelDecl();
00330
00331 virtual void SetMaxErrors(unsigned N) {
00332 MaxErrors = N;
00333 }
00334
00335 virtual unsigned GetNumErrors() const {
00336 return NumErrors;
00337 }
00338 };
00339 }
00340
00341 const Identifier *ParserImpl::GetOrCreateIdentifier(const Token &Tok) {
00342
00343 assert(Tok.kind == Token::Identifier && "Expected only identifier tokens.");
00344 std::string Name(Tok.start, Tok.length);
00345 IdentifierTabTy::iterator it = IdentifierTab.find(Name);
00346 if (it != IdentifierTab.end())
00347 return it->second;
00348
00349 Identifier *I = new Identifier(Name);
00350 IdentifierTab.insert(std::make_pair(Name, I));
00351
00352 return I;
00353 }
00354
00355 Decl *ParserImpl::ParseTopLevelDecl() {
00356
00357 while (Tok.kind != Token::EndOfFile) {
00358
00359 if (Tok.kind == Token::LParen) {
00360 DeclResult Res = ParseCommandDecl();
00361 if (Res.isValid())
00362 return Res.get();
00363 } else {
00364 Error("expected '(' token.");
00365 ConsumeAnyToken();
00366 }
00367 }
00368
00369 return 0;
00370 }
00371
00376 DeclResult ParserImpl::ParseCommandDecl() {
00377 ConsumeLParen();
00378
00379 if (!Tok.isKeyword()) {
00380 Error("malformed command.");
00381 SkipUntilRParen();
00382 return DeclResult();
00383 }
00384
00385 switch (Tok.kind) {
00386 case Token::KWQuery:
00387 return ParseQueryCommand();
00388
00389 default:
00390 Error("malformed command (unexpected keyword).");
00391 SkipUntilRParen();
00392 return DeclResult();
00393 }
00394 }
00395
00400 DeclResult ParserImpl::ParseQueryCommand() {
00401 std::vector<ExprHandle> Constraints;
00402 std::vector<ExprHandle> Values;
00403 std::vector<const Array*> Objects;
00404 ExprResult Res;
00405
00406
00407 ExprSymTab.clear();
00408 VersionSymTab.clear();
00409
00410 ConsumeExpectedToken(Token::KWQuery);
00411 if (Tok.kind != Token::LSquare) {
00412 Error("malformed query, expected constraint list.");
00413 SkipUntilRParen();
00414 return DeclResult();
00415 }
00416
00417 ConsumeExpectedToken(Token::LSquare);
00418
00419 while (Tok.kind != Token::RSquare) {
00420 if (Tok.kind == Token::EndOfFile) {
00421 Error("unexpected end of file.");
00422 Res = ExprResult(ConstantExpr::alloc(0, Expr::Bool));
00423 goto exit;
00424 }
00425
00426 ExprResult Constraint = ParseExpr(TypeResult(Expr::Bool));
00427 if (Constraint.isValid())
00428 Constraints.push_back(Constraint.get());
00429 }
00430 ConsumeRSquare();
00431
00432 Res = ParseExpr(TypeResult(Expr::Bool));
00433 if (!Res.isValid())
00434 Res = ExprResult(ConstantExpr::alloc(0, Expr::Bool));
00435
00436
00437 if (Tok.kind == Token::RParen)
00438 goto exit;
00439
00440 ConsumeExpectedToken(Token::LSquare);
00441
00442 while (Tok.kind != Token::RSquare) {
00443 if (Tok.kind == Token::EndOfFile) {
00444 Error("unexpected end of file.");
00445 goto exit;
00446 }
00447
00448 ExprResult Res = ParseExpr(TypeResult());
00449 if (Res.isValid())
00450 Values.push_back(Res.get());
00451 }
00452 ConsumeRSquare();
00453
00454
00455 if (Tok.kind == Token::RParen)
00456 goto exit;
00457
00458 ConsumeExpectedToken(Token::LSquare);
00459
00460 while (Tok.kind != Token::RSquare) {
00461 if (Tok.kind == Token::EndOfFile) {
00462 Error("unexpected end of file.");
00463 goto exit;
00464 }
00465
00466
00467 if (Tok.kind != Token::Identifier) {
00468 Error("unexpected token.");
00469 ConsumeToken();
00470 continue;
00471 }
00472
00473 Token LTok = Tok;
00474 const Identifier *Label = GetOrCreateIdentifier(Tok);
00475 ConsumeToken();
00476
00477
00478 const ArrayDecl *AD = ArraySymTab[Label];
00479 if (!AD) {
00480
00481 unsigned Id = atoi(&Label->Name.c_str()[3]);
00482 AD = new ArrayDecl(Label, 0, 32, 8, new Array(0, Id, 0));
00483 }
00484
00485 Objects.push_back(AD->Root);
00486 }
00487 ConsumeRSquare();
00488
00489 exit:
00490 if (Tok.kind != Token::EndOfFile)
00491 ExpectRParen("unexpected argument to 'query'.");
00492 return new QueryCommand(Constraints, Res.get(), Values, Objects);
00493 }
00494
00497 NumberOrExprResult ParserImpl::ParseNumberOrExpr() {
00498 if (Tok.kind == Token::Number){
00499 Token Num = Tok;
00500 ConsumeToken();
00501 return NumberOrExprResult(Num);
00502 } else {
00503 return NumberOrExprResult(ParseExpr(TypeResult()));
00504 }
00505 }
00506
00515 ExprResult ParserImpl::ParseExpr(TypeResult ExpectedType) {
00516
00517 if (Tok.kind == Token::EndOfFile) {
00518 Error("unexpected end of file.");
00519 return ExprResult();
00520 }
00521
00522 if (Tok.kind == Token::KWFalse || Tok.kind == Token::KWTrue) {
00523 bool Value = Tok.kind == Token::KWTrue;
00524 ConsumeToken();
00525 return ExprResult(ConstantExpr::alloc(Value, Expr::Bool));
00526 }
00527
00528 if (Tok.kind == Token::Number) {
00529 if (!ExpectedType.isValid()) {
00530 Error("cannot infer type of number.");
00531 ConsumeToken();
00532 return ExprResult();
00533 }
00534
00535 return ParseNumber(ExpectedType.get());
00536 }
00537
00538 const Identifier *Label = 0;
00539 if (Tok.kind == Token::Identifier) {
00540 Token LTok = Tok;
00541 Label = GetOrCreateIdentifier(Tok);
00542 ConsumeToken();
00543
00544 if (Tok.kind != Token::Colon) {
00545 ExprSymTabTy::iterator it = ExprSymTab.find(Label);
00546
00547 if (it == ExprSymTab.end()) {
00548 Error("invalid expression label reference.", LTok);
00549 return ExprResult();
00550 }
00551
00552 return it->second;
00553 }
00554
00555 ConsumeToken();
00556 if (ExprSymTab.count(Label)) {
00557 Error("duplicate expression label definition.", LTok);
00558 Label = 0;
00559 }
00560 }
00561
00562 Token Start = Tok;
00563 ExprResult Res = ParseParenExpr(ExpectedType);
00564 if (!Res.isValid()) {
00565
00566
00567
00568
00569 if (Label && ExpectedType.isValid()) {
00570 ref<Expr> Value = ConstantExpr::alloc(0, ExpectedType.get());
00571 ExprSymTab.insert(std::make_pair(Label, Value));
00572 }
00573 return Res;
00574 } else if (ExpectedType.isValid()) {
00575
00576 if (Res.get()->getWidth() != ExpectedType.get()) {
00577
00578 Error("expression has incorrect type.", Start);
00579 return ExprResult();
00580 }
00581 }
00582
00583 if (Label)
00584 ExprSymTab.insert(std::make_pair(Label, Res.get()));
00585 return Res;
00586 }
00587
00588
00589 enum MacroKind {
00590 eMacroKind_Not = Expr::LastKind + 1,
00591 eMacroKind_Neg,
00592 eMacroKind_ReadLSB,
00593 eMacroKind_ReadMSB,
00594 eMacroKind_Concat,
00595 eMacroKind_LastMacroKind = eMacroKind_ReadMSB
00596 };
00597
00608 static bool LookupExprInfo(const Token &Tok, unsigned &Kind,
00609 bool &IsFixed, int &NumArgs) {
00610 #define SetOK(kind, isfixed, numargs) (Kind=kind, IsFixed=isfixed,\
00611 NumArgs=numargs, true)
00612 assert(Tok.kind == Token::Identifier && "Unexpected token.");
00613
00614 switch (Tok.length) {
00615 case 2:
00616 if (memcmp(Tok.start, "Eq", 2) == 0)
00617 return SetOK(Expr::Eq, false, 2);
00618 if (memcmp(Tok.start, "Ne", 2) == 0)
00619 return SetOK(Expr::Ne, false, 2);
00620
00621 if (memcmp(Tok.start, "Or", 2) == 0)
00622 return SetOK(Expr::Or, true, 2);
00623 break;
00624
00625 case 3:
00626 if (memcmp(Tok.start, "Add", 3) == 0)
00627 return SetOK(Expr::Add, true, 2);
00628 if (memcmp(Tok.start, "Sub", 3) == 0)
00629 return SetOK(Expr::Sub, true, 2);
00630 if (memcmp(Tok.start, "Mul", 3) == 0)
00631 return SetOK(Expr::Mul, true, 2);
00632
00633 if (memcmp(Tok.start, "And", 3) == 0)
00634 return SetOK(Expr::And, true, 2);
00635 if (memcmp(Tok.start, "Shl", 3) == 0)
00636 return SetOK(Expr::Shl, true, 2);
00637 if (memcmp(Tok.start, "Xor", 3) == 0)
00638 return SetOK(Expr::Xor, true, 2);
00639
00640 if (memcmp(Tok.start, "Not", 3) == 0)
00641 return SetOK(eMacroKind_Not, true, 1);
00642 if (memcmp(Tok.start, "Neg", 3) == 0)
00643 return SetOK(eMacroKind_Neg, true, 1);
00644 if (memcmp(Tok.start, "Ult", 3) == 0)
00645 return SetOK(Expr::Ult, false, 2);
00646 if (memcmp(Tok.start, "Ule", 3) == 0)
00647 return SetOK(Expr::Ule, false, 2);
00648 if (memcmp(Tok.start, "Ugt", 3) == 0)
00649 return SetOK(Expr::Ugt, false, 2);
00650 if (memcmp(Tok.start, "Uge", 3) == 0)
00651 return SetOK(Expr::Uge, false, 2);
00652 if (memcmp(Tok.start, "Slt", 3) == 0)
00653 return SetOK(Expr::Slt, false, 2);
00654 if (memcmp(Tok.start, "Sle", 3) == 0)
00655 return SetOK(Expr::Sle, false, 2);
00656 if (memcmp(Tok.start, "Sgt", 3) == 0)
00657 return SetOK(Expr::Sgt, false, 2);
00658 if (memcmp(Tok.start, "Sge", 3) == 0)
00659 return SetOK(Expr::Sge, false, 2);
00660 break;
00661
00662 case 4:
00663 if (memcmp(Tok.start, "Read", 4) == 0)
00664 return SetOK(Expr::Read, true, -1);
00665 if (memcmp(Tok.start, "AShr", 4) == 0)
00666 return SetOK(Expr::AShr, true, 2);
00667 if (memcmp(Tok.start, "LShr", 4) == 0)
00668 return SetOK(Expr::LShr, true, 2);
00669
00670 if (memcmp(Tok.start, "UDiv", 4) == 0)
00671 return SetOK(Expr::UDiv, true, 2);
00672 if (memcmp(Tok.start, "SDiv", 4) == 0)
00673 return SetOK(Expr::SDiv, true, 2);
00674 if (memcmp(Tok.start, "URem", 4) == 0)
00675 return SetOK(Expr::URem, true, 2);
00676 if (memcmp(Tok.start, "SRem", 4) == 0)
00677 return SetOK(Expr::SRem, true, 2);
00678
00679 if (memcmp(Tok.start, "SExt", 4) == 0)
00680 return SetOK(Expr::SExt, false, 1);
00681 if (memcmp(Tok.start, "ZExt", 4) == 0)
00682 return SetOK(Expr::ZExt, false, 1);
00683 break;
00684
00685 case 6:
00686 if (memcmp(Tok.start, "Concat", 6) == 0)
00687 return SetOK(eMacroKind_Concat, false, -1);
00688 if (memcmp(Tok.start, "Select", 6) == 0)
00689 return SetOK(Expr::Select, false, 3);
00690 break;
00691
00692 case 7:
00693 if (memcmp(Tok.start, "Extract", 7) == 0)
00694 return SetOK(Expr::Extract, false, -1);
00695 if (memcmp(Tok.start, "ReadLSB", 7) == 0)
00696 return SetOK(eMacroKind_ReadLSB, true, -1);
00697 if (memcmp(Tok.start, "ReadMSB", 7) == 0)
00698 return SetOK(eMacroKind_ReadMSB, true, -1);
00699 break;
00700 }
00701
00702 return false;
00703 #undef SetOK
00704 }
00705
00713 ExprResult ParserImpl::ParseParenExpr(TypeResult FIXME_UNUSED) {
00714 if (Tok.kind != Token::LParen) {
00715 Error("unexpected token.");
00716 ConsumeAnyToken();
00717 return ExprResult();
00718 }
00719
00720 ConsumeLParen();
00721
00722
00723 if (Tok.kind == Token::KWWidth) {
00724 TypeResult ExpectedType = ParseTypeSpecifier();
00725
00726 if (Tok.kind != Token::Number) {
00727 Error("coercion can only apply to a number.");
00728 SkipUntilRParen();
00729 return ExprResult();
00730 }
00731
00732
00733 ExprResult Res;
00734 if (ExpectedType.isValid())
00735 Res = ParseNumber(ExpectedType.get());
00736 else
00737 ConsumeToken();
00738
00739 ExpectRParen("unexpected argument in coercion.");
00740 return Res;
00741 }
00742
00743 if (Tok.kind != Token::Identifier) {
00744 Error("unexpected token, expected expression.");
00745 SkipUntilRParen();
00746 return ExprResult();
00747 }
00748
00749 Token Name = Tok;
00750 ConsumeToken();
00751
00752
00753 Token TypeTok = Tok;
00754 bool HasType = TypeTok.kind == Token::KWWidth;
00755 TypeResult Type = HasType ? ParseTypeSpecifier() : Expr::Bool;
00756
00757
00758
00759
00760 if (!Type.isValid()) {
00761 SkipUntilRParen();
00762 return ExprResult();
00763 }
00764 Expr::Width ResTy = Type.get();
00765
00766 unsigned ExprKind;
00767 bool IsFixed;
00768 int NumArgs;
00769 if (!LookupExprInfo(Name, ExprKind, IsFixed, NumArgs)) {
00770
00771
00772
00773 Error("unknown expression kind.", Name);
00774 SkipUntilRParen();
00775 return ExprResult();
00776 }
00777
00778
00779 if (NumArgs == -1) {
00780 switch (ExprKind) {
00781 case eMacroKind_Concat:
00782 return ParseConcatParenExpr(Name, ResTy);
00783
00784 case Expr::Extract:
00785 return ParseExtractParenExpr(Name, ResTy);
00786
00787 case eMacroKind_ReadLSB:
00788 case eMacroKind_ReadMSB:
00789 case Expr::Read:
00790 return ParseAnyReadParenExpr(Name, ExprKind, ResTy);
00791
00792 default:
00793 Error("internal error, unimplemented special form.", Name);
00794 SkipUntilRParen();
00795 return ExprResult(ConstantExpr::alloc(0, ResTy));
00796 }
00797 }
00798
00799 switch (NumArgs) {
00800 case 1:
00801 return ParseUnaryParenExpr(Name, ExprKind, IsFixed, ResTy);
00802 case 2:
00803 return ParseBinaryParenExpr(Name, ExprKind, IsFixed, ResTy);
00804 case 3:
00805 if (ExprKind == Expr::Select)
00806 return ParseSelectParenExpr(Name, ResTy);
00807 default:
00808 assert(0 && "Invalid argument kind (number of args).");
00809 return ExprResult();
00810 }
00811 }
00812
00813 ExprResult ParserImpl::ParseUnaryParenExpr(const Token &Name,
00814 unsigned Kind, bool IsFixed,
00815 Expr::Width ResTy) {
00816 if (Tok.kind == Token::RParen) {
00817 Error("unexpected end of arguments.", Name);
00818 ConsumeRParen();
00819 return ConstantExpr::alloc(0, ResTy);
00820 }
00821
00822 ExprResult Arg = ParseExpr(IsFixed ? ResTy : TypeResult());
00823 if (!Arg.isValid())
00824 Arg = ConstantExpr::alloc(0, ResTy);
00825
00826 ExpectRParen("unexpected argument in unary expression.");
00827 ExprHandle E = Arg.get();
00828 switch (Kind) {
00829 case eMacroKind_Not:
00830 return EqExpr::alloc(ConstantExpr::alloc(0, E->getWidth()), E);
00831 case eMacroKind_Neg:
00832 return SubExpr::alloc(ConstantExpr::alloc(0, E->getWidth()), E);
00833 case Expr::SExt:
00834
00835 return SExtExpr::alloc(E, ResTy);
00836 case Expr::ZExt:
00837
00838 return ZExtExpr::alloc(E, ResTy);
00839 default:
00840 Error("internal error, unhandled kind.", Name);
00841 return ConstantExpr::alloc(0, ResTy);
00842 }
00843 }
00844
00851 void ParserImpl::ParseMatchedBinaryArgs(const Token &Name,
00852 TypeResult ExpectType,
00853 ExprResult &LHS, ExprResult &RHS) {
00854 if (Tok.kind == Token::RParen) {
00855 Error("unexpected end of arguments.", Name);
00856 ConsumeRParen();
00857 return;
00858 }
00859
00860
00861
00862 if (ExpectType.isValid()) {
00863 LHS = ParseExpr(ExpectType);
00864 if (Tok.kind == Token::RParen) {
00865 Error("unexpected end of arguments.", Name);
00866 ConsumeRParen();
00867 return;
00868 }
00869 RHS = ParseExpr(ExpectType);
00870 } else {
00871 NumberOrExprResult LHS_NOE = ParseNumberOrExpr();
00872
00873 if (Tok.kind == Token::RParen) {
00874 Error("unexpected end of arguments.", Name);
00875 ConsumeRParen();
00876 return;
00877 }
00878
00879 if (LHS_NOE.isNumber()) {
00880 NumberOrExprResult RHS_NOE = ParseNumberOrExpr();
00881
00882 if (RHS_NOE.isNumber()) {
00883 Error("ambiguous arguments to expression.", Name);
00884 } else {
00885 RHS = RHS_NOE.getExpr();
00886 if (RHS.isValid())
00887 LHS = ParseNumberToken(RHS.get()->getWidth(), LHS_NOE.getNumber());
00888 }
00889 } else {
00890 LHS = LHS_NOE.getExpr();
00891 if (!LHS.isValid()) {
00892
00893 RHS = ParseExpr(TypeResult());
00894 } else {
00895 RHS = ParseExpr(LHS.get()->getWidth());
00896 }
00897 }
00898 }
00899
00900 ExpectRParen("unexpected argument to expression.");
00901 }
00902
00903 ExprResult ParserImpl::ParseBinaryParenExpr(const Token &Name,
00904 unsigned Kind, bool IsFixed,
00905 Expr::Width ResTy) {
00906 ExprResult LHS, RHS;
00907 ParseMatchedBinaryArgs(Name, IsFixed ? TypeResult(ResTy) : TypeResult(),
00908 LHS, RHS);
00909 if (!LHS.isValid() || !RHS.isValid())
00910 return ConstantExpr::alloc(0, ResTy);
00911
00912 ref<Expr> LHS_E = LHS.get(), RHS_E = RHS.get();
00913 if (LHS_E->getWidth() != RHS_E->getWidth()) {
00914 Error("type widths do not match in binary expression", Name);
00915 return ConstantExpr::alloc(0, ResTy);
00916 }
00917
00918 switch (Kind) {
00919 case Expr::Add: return AddExpr::alloc(LHS_E, RHS_E);
00920 case Expr::Sub: return SubExpr::alloc(LHS_E, RHS_E);
00921 case Expr::Mul: return MulExpr::alloc(LHS_E, RHS_E);
00922 case Expr::UDiv: return UDivExpr::alloc(LHS_E, RHS_E);
00923 case Expr::SDiv: return SDivExpr::alloc(LHS_E, RHS_E);
00924 case Expr::URem: return URemExpr::alloc(LHS_E, RHS_E);
00925 case Expr::SRem: return SRemExpr::alloc(LHS_E, RHS_E);
00926
00927 case Expr::AShr: return AShrExpr::alloc(LHS_E, RHS_E);
00928 case Expr::LShr: return LShrExpr::alloc(LHS_E, RHS_E);
00929 case Expr::Shl: return AndExpr::alloc(LHS_E, RHS_E);
00930
00931 case Expr::And: return AndExpr::alloc(LHS_E, RHS_E);
00932 case Expr::Or: return OrExpr::alloc(LHS_E, RHS_E);
00933 case Expr::Xor: return XorExpr::alloc(LHS_E, RHS_E);
00934
00935 case Expr::Eq: return EqExpr::alloc(LHS_E, RHS_E);
00936 case Expr::Ne: return NeExpr::alloc(LHS_E, RHS_E);
00937 case Expr::Ult: return UltExpr::alloc(LHS_E, RHS_E);
00938 case Expr::Ule: return UleExpr::alloc(LHS_E, RHS_E);
00939 case Expr::Ugt: return UgtExpr::alloc(LHS_E, RHS_E);
00940 case Expr::Uge: return UgeExpr::alloc(LHS_E, RHS_E);
00941 case Expr::Slt: return SltExpr::alloc(LHS_E, RHS_E);
00942 case Expr::Sle: return SleExpr::alloc(LHS_E, RHS_E);
00943 case Expr::Sgt: return SgtExpr::alloc(LHS_E, RHS_E);
00944 case Expr::Sge: return SgeExpr::alloc(LHS_E, RHS_E);
00945 default:
00946 Error("FIXME: unhandled kind.", Name);
00947 return ConstantExpr::alloc(0, ResTy);
00948 }
00949 }
00950
00951 ExprResult ParserImpl::ParseSelectParenExpr(const Token &Name,
00952 Expr::Width ResTy) {
00953
00954 if (Tok.kind == Token::RParen) {
00955 Error("unexpected end of arguments.", Name);
00956 ConsumeRParen();
00957 return ConstantExpr::alloc(0, ResTy);
00958 }
00959
00960 ExprResult Cond = ParseExpr(Expr::Bool);
00961 ExprResult LHS, RHS;
00962 ParseMatchedBinaryArgs(Name, ResTy, LHS, RHS);
00963 if (!Cond.isValid() || !LHS.isValid() || !RHS.isValid())
00964 return ConstantExpr::alloc(0, ResTy);
00965 return SelectExpr::alloc(Cond.get(), LHS.get(), RHS.get());
00966 }
00967
00968
00969
00970
00971 ExprResult ParserImpl::ParseConcatParenExpr(const Token &Name,
00972 Expr::Width ResTy) {
00973 std::vector<ExprHandle> Kids;
00974
00975 unsigned Width = 0;
00976 while (Tok.kind != Token::RParen) {
00977 ExprResult E = ParseExpr(TypeResult());
00978
00979
00980 if (!E.isValid()) {
00981 SkipUntilRParen();
00982 return ConstantExpr::alloc(0, ResTy);
00983 }
00984
00985 Kids.push_back(E.get());
00986 Width += E.get()->getWidth();
00987 }
00988
00989 ConsumeRParen();
00990
00991 if (Width != ResTy) {
00992 Error("concat does not match expected result size.");
00993 return ConstantExpr::alloc(0, ResTy);
00994 }
00995
00996 return ConcatExpr::createN(Kids.size(), &Kids[0]);
00997 }
00998
00999 ExprResult ParserImpl::ParseExtractParenExpr(const Token &Name,
01000 Expr::Width ResTy) {
01001
01002 ExprResult OffsetExpr = ParseNumber(Expr::Int32);
01003 ExprResult Child = ParseExpr(TypeResult());
01004
01005 ExpectRParen("unexpected argument to expression.");
01006
01007 if (!OffsetExpr.isValid() || !Child.isValid())
01008 return ConstantExpr::alloc(0, ResTy);
01009
01010 unsigned Offset =
01011 (unsigned) cast<ConstantExpr>(OffsetExpr.get())->getConstantValue();
01012
01013 if (Offset + ResTy > Child.get()->getWidth()) {
01014 Error("extract out-of-range of child expression.", Name);
01015 return ConstantExpr::alloc(0, ResTy);
01016 }
01017
01018 return ExtractExpr::alloc(Child.get(), Offset, ResTy);
01019 }
01020
01021 ExprResult ParserImpl::ParseAnyReadParenExpr(const Token &Name,
01022 unsigned Kind,
01023 Expr::Width ResTy) {
01024 NumberOrExprResult Index = ParseNumberOrExpr();
01025 VersionResult Array = ParseVersionSpecifier();
01026 ExpectRParen("unexpected argument in read expression.");
01027
01028 if (!Array.isValid())
01029 return ConstantExpr::alloc(0, ResTy);
01030
01031
01032
01033 Expr::Width ArrayDomainType = Expr::Int32;
01034 Expr::Width ArrayRangeType = Expr::Int8;
01035
01036
01037 ExprResult IndexExpr;
01038 if (Index.isNumber())
01039 IndexExpr = ParseNumberToken(ArrayDomainType, Index.getNumber());
01040 else
01041 IndexExpr = Index.getExpr();
01042
01043 if (!IndexExpr.isValid())
01044 return ConstantExpr::alloc(0, ResTy);
01045 else if (IndexExpr.get()->getWidth() != ArrayDomainType) {
01046 Error("index width does not match array domain.");
01047 return ConstantExpr::alloc(0, ResTy);
01048 }
01049
01050
01051
01052 switch (Kind) {
01053 default:
01054 assert(0 && "Invalid kind.");
01055 return ConstantExpr::alloc(0, ResTy);
01056 case eMacroKind_ReadLSB:
01057 case eMacroKind_ReadMSB: {
01058 unsigned NumReads = ResTy / ArrayRangeType;
01059 if (ResTy != NumReads*ArrayRangeType) {
01060 Error("invalid ordered read (not multiple of range type).", Name);
01061 return ConstantExpr::alloc(0, ResTy);
01062 }
01063 std::vector<ExprHandle> Kids;
01064 Kids.reserve(NumReads);
01065 ExprHandle Index = IndexExpr.get();
01066 for (unsigned i=0; i<NumReads; ++i) {
01067
01068 ExprHandle OffsetIndex = AddExpr::create(IndexExpr.get(),
01069 ConstantExpr::alloc(i, ArrayDomainType));
01070 Kids.push_back(ReadExpr::alloc(Array.get(), OffsetIndex));
01071 }
01072 if (Kind == eMacroKind_ReadLSB)
01073 std::reverse(Kids.begin(), Kids.end());
01074 return ConcatExpr::createN(NumReads, &Kids[0]);
01075 }
01076 case Expr::Read:
01077 return ReadExpr::alloc(Array.get(), IndexExpr.get());
01078 }
01079 }
01080
01083 VersionResult ParserImpl::ParseVersionSpecifier() {
01084 const Identifier *Label = 0;
01085 if (Tok.kind == Token::Identifier) {
01086 Token LTok = Tok;
01087 Label = GetOrCreateIdentifier(Tok);
01088 ConsumeToken();
01089
01090
01091 if (memcmp(Label->Name.c_str(), "arr", 3) == 0) {
01092
01093 const ArrayDecl *&A = ArraySymTab[Label];
01094 if (!A) {
01095 unsigned id = atoi(&Label->Name.c_str()[3]);
01096 Array *root = new Array(0, id, 0);
01097 ArrayDecl *AD = new ArrayDecl(Label, 0, 32, 8, root);
01098
01099 VersionSymTab.insert(std::make_pair(Label,
01100 UpdateList(root, true, NULL)));
01101 ArraySymTab.insert(std::make_pair(Label, AD));
01102 }
01103 }
01104
01105 if (Tok.kind != Token::Colon) {
01106 VersionSymTabTy::iterator it = VersionSymTab.find(Label);
01107
01108 if (it == VersionSymTab.end()) {
01109 Error("invalid update list label reference.", LTok);
01110 return VersionResult(false,
01111 UpdateList(0, true, NULL));
01112 }
01113
01114 return it->second;
01115 }
01116
01117 ConsumeToken();
01118 if (VersionSymTab.count(Label)) {
01119 Error("duplicate update list label definition.", LTok);
01120 Label = 0;
01121 }
01122 }
01123
01124 Token Start = Tok;
01125 VersionResult Res = ParseVersion();
01126
01127 if (!Res.isValid())
01128 Res = VersionResult(false,
01129 UpdateList(0, true, NULL));
01130
01131 if (Label)
01132 VersionSymTab.insert(std::make_pair(Label, Res.get()));
01133 return Res;
01134 }
01135
01139 VersionResult ParserImpl::ParseVersion() {
01140 if (Tok.kind != Token::LSquare)
01141 return VersionResult(false, UpdateList(0, false, NULL));
01142
01143 std::vector< std::pair<NumberOrExprResult, NumberOrExprResult> > Writes;
01144 ConsumeLSquare();
01145 for (;;) {
01146
01147
01148
01149
01150 NumberOrExprResult LHS = ParseNumberOrExpr();
01151
01152 if (Tok.kind != Token::Equals) {
01153 Error("expected '='.", Tok);
01154 break;
01155 }
01156
01157 ConsumeToken();
01158 NumberOrExprResult RHS = ParseNumberOrExpr();
01159
01160 Writes.push_back(std::make_pair(LHS, RHS));
01161
01162 if (Tok.kind == Token::Comma)
01163 ConsumeToken();
01164 else
01165 break;
01166 }
01167 ExpectRSquare("expected close of update list");
01168
01169 VersionHandle Base(0, false, NULL);
01170
01171
01172 if (Tok.kind != Token::At) {
01173 Array *root = new Array(0, 0, 0);
01174 Base = UpdateList(root, false, NULL);
01175 } else {
01176 ConsumeToken();
01177
01178 VersionResult BaseRes = ParseVersionSpecifier();
01179 if (!BaseRes.isValid())
01180 return BaseRes;
01181
01182 Base = BaseRes.get();
01183 }
01184
01185 Expr::Width ArrayDomainType = Expr::Int32;
01186 Expr::Width ArrayRangeType = Expr::Int8;
01187
01188 for (std::vector< std::pair<NumberOrExprResult, NumberOrExprResult> >::reverse_iterator
01189 it = Writes.rbegin(), ie = Writes.rend(); it != ie; ++it) {
01190 ExprResult LHS, RHS;
01191
01192
01193 if (it->first.isNumber()) {
01194 LHS = ParseNumberToken(ArrayDomainType, it->first.getNumber());
01195 } else {
01196 LHS = it->first.getExpr();
01197 if (LHS.isValid() && LHS.get()->getWidth() != ArrayDomainType) {
01198
01199
01200 Error("invalid value in write index (doesn't match domain).", Tok);
01201 LHS = ExprResult();
01202 }
01203 }
01204
01205 if (it->second.isNumber()) {
01206 RHS = ParseNumberToken(ArrayRangeType, it->second.getNumber());
01207 } else {
01208 RHS = it->second.getExpr();
01209 if (RHS.isValid() && RHS.get()->getWidth() != ArrayRangeType) {
01210
01211
01212 Error("invalid value in write assignment (doesn't match range).", Tok);
01213 RHS = ExprResult();
01214 }
01215 }
01216
01217 if (LHS.isValid() && RHS.isValid())
01218 Base.extend(LHS.get(), RHS.get());
01219 }
01220
01221 return Base;
01222 }
01223
01225 ExprResult ParserImpl::ParseNumber(Expr::Width Type) {
01226 ExprResult Res = ParseNumberToken(Type, Tok);
01227 ConsumeExpectedToken(Token::Number);
01228 return Res;
01229 }
01230
01233 ExprResult ParserImpl::ParseNumberToken(Expr::Width Type, const Token &Tok) {
01234 const char *S = Tok.start;
01235 unsigned N = Tok.length;
01236 unsigned Radix = 10, RadixBits = 4;
01237 bool HasMinus = false;
01238
01239
01240 if (S[0] == '+') {
01241 ++S;
01242 --N;
01243 } else if (S[0] == '-') {
01244 HasMinus = true;
01245 ++S;
01246 --N;
01247 }
01248
01249
01250 if ((Tok.length >= 2 && S[0] == '0') &&
01251 (S[1] == 'b' || S[1] == 'o' || S[1] == 'x')) {
01252 if (S[1] == 'b') {
01253 Radix = 2;
01254 RadixBits = 1;
01255 } else if (S[1] == 'o') {
01256 Radix = 8;
01257 RadixBits = 3;
01258 } else {
01259 Radix = 16;
01260 RadixBits = 4;
01261 }
01262 S += 2;
01263 N -= 2;
01264
01265
01266 if (!N) {
01267 Error("invalid numeric token (no digits).", Tok);
01268 return ConstantExpr::alloc(0, Type);
01269 }
01270 }
01271
01272
01273 APInt Val(std::max(64U, RadixBits * N), 0);
01274 APInt RadixVal(Val.getBitWidth(), Radix);
01275 APInt DigitVal(Val.getBitWidth(), 0);
01276 for (unsigned i=0; i<N; ++i) {
01277 unsigned Digit, Char = S[i];
01278
01279 if (Char == '_')
01280 continue;
01281
01282 if ('0' <= Char && Char <= '9')
01283 Digit = Char - '0';
01284 else if ('a' <= Char && Char <= 'z')
01285 Digit = Char - 'a' + 10;
01286 else if ('A' <= Char && Char <= 'Z')
01287 Digit = Char - 'A' + 10;
01288 else {
01289 Error("invalid character in numeric token.", Tok);
01290 return ConstantExpr::alloc(0, Type);
01291 }
01292
01293 if (Digit >= Radix) {
01294 Error("invalid character in numeric token (out of range).", Tok);
01295 return ConstantExpr::alloc(0, Type);
01296 }
01297
01298 DigitVal = Digit;
01299 Val = Val * RadixVal + DigitVal;
01300 }
01301
01302
01303 if (HasMinus)
01304 Val = -Val;
01305
01306 if (Type < Val.getBitWidth())
01307 Val = Val.trunc(Type);
01308
01309 return ExprResult(ConstantExpr::alloc(Val.getZExtValue(), Type));
01310 }
01311
01315 TypeResult ParserImpl::ParseTypeSpecifier() {
01316 assert(Tok.kind == Token::KWWidth && "Unexpected token.");
01317
01318
01319 Token TypeTok = Tok;
01320 int width = atoi(std::string(Tok.start+1,Tok.length-1).c_str());
01321 ConsumeToken();
01322
01323
01324 return TypeResult(width);
01325 }
01326
01327 void ParserImpl::Error(const char *Message, const Token &At) {
01328 ++NumErrors;
01329 if (MaxErrors && NumErrors >= MaxErrors)
01330 return;
01331
01332 llvm::cerr << Filename
01333 << ":" << At.line << ":" << At.column
01334 << ": error: " << Message << "\n";
01335
01336
01337 if (At.kind == Token::EndOfFile)
01338 return;
01339
01340
01341 const char *LineBegin = At.start, *LineEnd = At.start,
01342 *BufferBegin = TheMemoryBuffer->getBufferStart(),
01343 *BufferEnd = TheMemoryBuffer->getBufferEnd();
01344
01345
01346 while (LineBegin > BufferBegin &&
01347 LineBegin[-1] != '\r' && LineBegin[-1] != '\n')
01348 --LineBegin;
01349 while (LineEnd < BufferEnd &&
01350 LineEnd[0] != '\r' && LineEnd[0] != '\n')
01351 ++LineEnd;
01352
01353
01354 llvm::cerr << std::string(LineBegin, LineEnd) << "\n";
01355
01356
01357
01358 for (const char *S=LineBegin; S != At.start; ++S)
01359 llvm::cerr << (isspace(*S) ? *S : ' ');
01360 if (At.length > 1) {
01361 for (unsigned i=0; i<At.length; ++i)
01362 llvm::cerr << '~';
01363 } else
01364 llvm::cerr << '^';
01365 llvm::cerr << '\n';
01366 }
01367
01368
01369
01370
01371 Decl::Decl(DeclKind _Kind) : Kind(_Kind) {}
01372
01373 void ArrayDecl::dump() {
01374 std::cout << "array " << Name->Name << " : "
01375 << 'w' << Domain << " -> "
01376 << 'w' << Range << " = ";
01377
01378 if (Contents.empty()) {
01379 std::cout << "symbolic\n";
01380 } else {
01381 std::cout << '{';
01382 for (std::vector<ExprHandle>::const_iterator it = Contents.begin(),
01383 ie = Contents.end(); it != ie;) {
01384 std::cout << *it;
01385 if (++it != ie)
01386 std::cout << " ";
01387 }
01388 std::cout << "}\n";
01389 }
01390 }
01391
01392 void QueryCommand::dump() {
01393 const ExprHandle *ValuesBegin = 0, *ValuesEnd = 0;
01394 const Array * const* ObjectsBegin = 0, * const* ObjectsEnd = 0;
01395 if (!Values.empty()) {
01396 ValuesBegin = &Values[0];
01397 ValuesEnd = ValuesBegin + Values.size();
01398 }
01399 if (!Objects.empty()) {
01400 ObjectsBegin = &Objects[0];
01401 ObjectsEnd = ObjectsBegin + Objects.size();
01402 }
01403 ExprPPrinter::printQuery(std::cout, ConstraintManager(Constraints),
01404 Query, ValuesBegin, ValuesEnd,
01405 ObjectsBegin, ObjectsEnd);
01406 }
01407
01408
01409
01410 Parser::Parser() {
01411 }
01412
01413 Parser::~Parser() {
01414 }
01415
01416 Parser *Parser::Create(const std::string Filename,
01417 const MemoryBuffer *MB) {
01418 ParserImpl *P = new ParserImpl(Filename, MB);
01419 P->Initialize();
01420 return P;
01421 }