1 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2 3 /* 4 * Main authors: 5 * Guido Tack <guido.tack@monash.edu> 6 */ 7 8 /* This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 11 12 #pragma once 13 14 // This is a workaround for a bug in flex that only shows up 15 // with the Microsoft C++ compiler 16 #if defined(_MSC_VER) 17 #define YY_NO_UNISTD_H 18 #ifdef __cplusplus 19 extern "C" int isatty(int); 20 #endif 21 #endif 22 23 // The Microsoft C++ compiler marks certain functions as deprecated, 24 // so let's take the alternative definitions 25 #if defined(_MSC_VER) 26 #define strdup _strdup 27 #define fileno _fileno 28 #endif 29 30 #if defined(_MSC_VER) 31 #pragma warning(disable : 4065) 32 #endif 33 34 namespace MiniZinc { 35 class ParserLocation; 36 } 37 #define YYLTYPE MiniZinc::ParserLocation 38 #define YYLTYPE_IS_DECLARED 1 39 #define YYLTYPE_IS_TRIVIAL 0 40 41 #include <minizinc/astexception.hh> 42 #include <minizinc/file_utils.hh> 43 #include <minizinc/model.hh> 44 #include <minizinc/parser.tab.hh> 45 46 #include <algorithm> 47 #include <cstdlib> 48 #include <cstring> 49 #include <iostream> 50 #include <map> 51 #include <string> 52 #include <utility> 53 #include <vector> 54 55 namespace MiniZinc { 56 57 struct ParseWorkItem { 58 Model* m; 59 IncludeI* ii; 60 std::string dirName; 61 std::string fileName; 62 bool isSTDLib; 63 bool isModelString; ParseWorkItemMiniZinc::ParseWorkItem64 ParseWorkItem(Model* m0, IncludeI* ii0, std::string dirName0, std::string fileName0, 65 bool isSTDLib0 = false, bool isModelString0 = false) 66 : m(m0), 67 ii(ii0), 68 dirName(std::move(dirName0)), 69 fileName(std::move(fileName0)), 70 isSTDLib(isSTDLib0), 71 isModelString(isModelString0) {} 72 }; 73 74 /// %State of the %MiniZinc parser 75 class ParserState { 76 public: ParserState(const std::string & f,const std::string & b,std::ostream & err0,const std::vector<std::string> & includePaths0,std::vector<ParseWorkItem> & files0,std::map<std::string,Model * > & seenModels0,MiniZinc::Model * model0,bool isDatafile0,bool isFlatZinc0,bool isSTDLib0,bool parseDocComments0)77 ParserState(const std::string& f, const std::string& b, std::ostream& err0, 78 const std::vector<std::string>& includePaths0, std::vector<ParseWorkItem>& files0, 79 std::map<std::string, Model*>& seenModels0, MiniZinc::Model* model0, bool isDatafile0, 80 bool isFlatZinc0, bool isSTDLib0, bool parseDocComments0) 81 : filename(f.c_str()), 82 buf(b.c_str()), 83 pos(0), 84 length(static_cast<unsigned int>(b.size())), 85 lineStartPos(0), 86 nTokenNextStart(1), 87 hadNewline(false), 88 includePaths(includePaths0), 89 files(files0), 90 seenModels(seenModels0), 91 model(model0), 92 isDatafile(isDatafile0), 93 isFlatZinc(isFlatZinc0), 94 isSTDLib(isSTDLib0), 95 parseDocComments(parseDocComments0), 96 hadError(false), 97 err(err0) {} 98 99 const char* filename; 100 101 void* yyscanner; 102 const char* buf; 103 unsigned int pos, length; 104 105 int lineStartPos; 106 int nTokenNextStart; 107 bool hadNewline; 108 109 const std::vector<std::string>& includePaths; 110 std::vector<ParseWorkItem>& files; 111 std::map<std::string, Model*>& seenModels; 112 MiniZinc::Model* model; 113 114 bool isDatafile; 115 bool isFlatZinc; 116 bool isSTDLib; 117 bool parseDocComments; 118 bool hadError; 119 std::vector<SyntaxError> syntaxErrors; 120 std::ostream& err; 121 122 std::string stringBuffer; 123 printCurrentLine(int firstCol,int lastCol)124 void printCurrentLine(int firstCol, int lastCol) { 125 const char* eol_c = strchr(buf + lineStartPos, '\n'); 126 if (eol_c != nullptr) { 127 if (eol_c == buf + lineStartPos) { 128 return; 129 } 130 err << std::string(buf + lineStartPos, eol_c - (buf + lineStartPos)); 131 } else { 132 err << buf + lineStartPos; 133 } 134 err << std::endl; 135 for (int i = 0; i < firstCol - 1; i++) { 136 err << " "; 137 } 138 for (int i = firstCol; i <= lastCol; i++) { 139 err << "^"; 140 } 141 err << std::endl; 142 } 143 fillBuffer(char * lexBuf,unsigned int lexBufSize)144 int fillBuffer(char* lexBuf, unsigned int lexBufSize) { 145 if (pos >= length) { 146 return 0; 147 } 148 int num = std::min(length - pos, lexBufSize); 149 memcpy(lexBuf, buf + pos, num); 150 pos += num; 151 return num; 152 } 153 154 std::string canonicalFilename(const std::string& f) const; 155 }; 156 157 Model* parse(Env& env, const std::vector<std::string>& filename, 158 const std::vector<std::string>& datafiles, const std::string& textModel, 159 const std::string& textModelName, const std::vector<std::string>& includePaths, 160 bool isFlatZinc, bool ignoreStdlib, bool parseDocComments, bool verbose, 161 std::ostream& err); 162 163 Model* parse_from_string(Env& env, const std::string& text, const std::string& filename, 164 const std::vector<std::string>& includePaths, bool isFlatZinc, 165 bool ignoreStdlib, bool parseDocComments, bool verbose, std::ostream& err, 166 std::vector<SyntaxError>& syntaxErrors); 167 168 Model* parse_data(Env& env, Model* m, const std::vector<std::string>& datafiles, 169 const std::vector<std::string>& includePaths, bool isFlatZinc, bool ignoreStdlib, 170 bool parseDocComments, bool verbose, std::ostream& err); 171 172 } // namespace MiniZinc 173