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 #include <minizinc/astexception.hh>
15 #include <minizinc/model.hh>
16 
17 #include <fstream>
18 #include <string>
19 #include <vector>
20 
21 namespace MiniZinc {
22 
23 class JSONError : public LocationException {
24 public:
JSONError(EnvI & env,const Location & loc,const std::string & msg)25   JSONError(EnvI& env, const Location& loc, const std::string& msg)
26       : LocationException(env, loc, msg) {}
what() const27   const char* what() const throw() override { return "MiniZinc: JSON parsing error"; }
28 };
29 
30 class JSONParser {
31 protected:
32   enum TokenT {
33     T_LIST_OPEN,
34     T_LIST_CLOSE,
35     T_OBJ_OPEN,
36     T_OBJ_CLOSE,
37     T_COMMA,
38     T_COLON,
39     T_STRING,
40     T_INT,
41     T_FLOAT,
42     T_BOOL,
43     T_NULL,
44     T_EOF
45   } _t;
46 
47   class Token;
48   EnvI& _env;
49   int _line;
50   int _column;
51   std::string _filename;
52   Location errLocation() const;
53   Token readToken(std::istream& is);
54   void expectToken(std::istream& is, TokenT t);
55   std::string expectString(std::istream& is);
56   void expectEof(std::istream& is);
57   Token parseEnumString(std::istream& is);
58   Expression* parseExp(std::istream& is, bool parseObjects = true, bool possibleString = true);
59   ArrayLit* parseArray(std::istream& is, bool possibleString = true);
60   Expression* parseObject(std::istream& is, bool possibleString = true);
61 
62   void parseModel(Model* m, std::istream& is, bool isData);
63   static Expression* coerceArray(TypeInst* intendedTI, ArrayLit* al);
64 
65 public:
JSONParser(EnvI & env)66   JSONParser(EnvI& env) : _env(env) {}
67   /// Parses \a filename as MiniZinc data and creates assign items in \a m
68   void parse(Model* m, const std::string& filename, bool isData = true);
69   /// Parses \a data as JSON-encoded MiniZinc data and creates assign items in \a m
70   void parseFromString(Model* m, const std::string& data, bool isData = true);
71   /// Check if file \a filename may contain JSON-encoded MiniZinc data
72   static bool fileIsJSON(const std::string& filename);
73   /// Check if string \a data may contain JSON-encoded MiniZinc data
74   static bool stringIsJSON(const std::string& data);
75 };
76 
77 }  // namespace MiniZinc
78