1 /********************* */
4 ** Top contributors (to current version):
5 ** Tim King, Morgan Deters, Christopher L. Conway
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2019 by the authors listed in the file AUTHORS
8 ** in the top-level source directory) and their institutional affiliations.
9 ** All rights reserved. See the file COPYING in the top-level source
10 ** directory for licensing information.\endverbatim
12 ** \brief Simple representation of S-expressions
14 ** Simple representation of S-expressions.
15 ** These are used when a simple, and obvious interface for basic
16 ** expressions is appropriate.
18 ** These are quite ineffecient.
19 ** These are totally disconnected from any ExprManager.
20 ** These keep unique copies of all of their children.
21 ** These are VERY overly verbose and keep much more data than is needed.
24 #include "cvc4_public.h"
34 #include "base/exception.h"
35 #include "options/language.h"
36 #include "util/integer.h"
37 #include "util/rational.h"
41 class CVC4_PUBLIC SExprKeyword
{
43 SExprKeyword(const std::string
& s
) : d_str(s
) {}
44 const std::string
& getString() const { return d_str
; }
48 }; /* class SExpr::Keyword */
51 * A simple S-expression. An S-expression is either an atom with a
52 * string value, or a list of other S-expressions.
54 class CVC4_PUBLIC SExpr
{
56 typedef SExprKeyword Keyword
;
60 SExpr
& operator=(const SExpr
& other
);
63 SExpr(const CVC4::Integer
& value
);
66 SExpr(long int value
);
67 SExpr(unsigned int value
);
68 SExpr(unsigned long int value
);
70 SExpr(const CVC4::Rational
& value
);
72 SExpr(const std::string
& value
);
75 * This constructs a string expression from a const char* value.
76 * This cannot be removed in order to support SExpr("foo").
77 * Given the other constructors this SExpr("foo") converts to bool.
78 * instead of SExpr(string("foo")).
80 SExpr(const char* value
);
83 * This adds a convenience wrapper to SExpr to cast from bools.
84 * This is internally handled as the strings "true" and "false"
87 SExpr(const Keyword
& value
);
88 SExpr(const std::vector
<SExpr
>& children
);
90 /** Is this S-expression an atom? */
93 /** Is this S-expression an integer? */
94 bool isInteger() const;
96 /** Is this S-expression a rational? */
97 bool isRational() const;
99 /** Is this S-expression a string? */
100 bool isString() const;
102 /** Is this S-expression a keyword? */
103 bool isKeyword() const;
106 * This wraps the toStream() printer.
107 * NOTE: toString() and getValue() may differ on Keywords based on
108 * the current language set in expr.
110 std::string
toString() const;
113 * Get the string value of this S-expression. This will cause an
114 * error if this S-expression is not an atom.
116 std::string
getValue() const;
119 * Get the integer value of this S-expression. This will cause an
120 * error if this S-expression is not an integer.
122 const CVC4::Integer
& getIntegerValue() const;
125 * Get the rational value of this S-expression. This will cause an
126 * error if this S-expression is not a rational.
128 const CVC4::Rational
& getRationalValue() const;
131 * Get the children of this S-expression. This will cause an error
132 * if this S-expression is not a list.
134 const std::vector
<SExpr
>& getChildren() const;
136 /** Is this S-expression equal to another? */
137 bool operator==(const SExpr
& s
) const;
139 /** Is this S-expression different from another? */
140 bool operator!=(const SExpr
& s
) const;
143 * This returns the best match in the following order:
145 * "true", "false" -> SExpr(value)
146 * | is and integer -> as integer
147 * | is a rational -> as rational
150 static SExpr
parseAtom(const std::string
& atom
);
153 * Parses a list of atoms.
155 static SExpr
parseListOfAtoms(const std::vector
<std::string
>& atoms
);
158 * Parses a list of list of atoms.
160 static SExpr
parseListOfListOfAtoms(
161 const std::vector
<std::vector
<std::string
> >& atoms_lists
);
164 * Outputs the SExpr onto the ostream out. This version reads defaults to the
165 * OutputLanguage, language::SetLanguage::getLanguage(out). The indent level
167 * set to 2 if PrettySExprs::getPrettySExprs() is on and is 0 otherwise.
169 static void toStream(std::ostream
& out
, const SExpr
& sexpr
);
172 * Outputs the SExpr onto the ostream out. This version sets the indent level
173 * to 2 if PrettySExprs::getPrettySExprs() is on.
175 static void toStream(std::ostream
& out
, const SExpr
& sexpr
,
176 OutputLanguage language
);
179 * Outputs the SExpr onto the ostream out.
180 * If the languageQuotesKeywords(language), then a top level keyword, " X",
181 * that needs quoting according to the SMT2 language standard is printed with
183 * Otherwise this prints using toStreamRec().
185 * TIM: Keywords that are children are not currently quoted. This seems
186 * incorrect but I am just reproduicing the old behavior even if it does not
190 static void toStream(std::ostream
& out
, const SExpr
& sexpr
,
191 OutputLanguage language
, int indent
);
195 * Simple printer for SExpr to an ostream.
196 * The current implementation is language independent.
198 static void toStreamRec(std::ostream
& out
, const SExpr
& sexpr
,
199 OutputLanguage language
, int indent
);
201 /** Returns true if this language quotes Keywords when printing. */
202 static bool languageQuotesKeywords(OutputLanguage language
);
212 /** The value of an atomic integer-valued S-expression. */
213 CVC4::Integer d_integerValue
;
215 /** The value of an atomic rational-valued S-expression. */
216 CVC4::Rational d_rationalValue
;
218 /** The value of an atomic S-expression. */
219 std::string d_stringValue
;
221 typedef std::vector
<SExpr
> SExprVector
;
224 * The children of a list S-expression.
225 * Whenever the SExpr isAtom() holds, this points at NULL.
227 * This should be a pointer in case the implementation of vector<SExpr> ever
228 * directly contained or allocated an SExpr. If this happened this would
230 * either the size being infinite or SExpr() being an infinite loop.
232 SExprVector
* d_children
;
235 /** Prints an SExpr. */
236 std::ostream
& operator<<(std::ostream
& out
, const SExpr
& sexpr
) CVC4_PUBLIC
;
239 * IOStream manipulator to pretty-print SExprs.
241 class CVC4_PUBLIC PrettySExprs
{
243 * The allocated index in ios_base for our setting.
245 static const int s_iosIndex
;
248 * When this manipulator is used, the setting is stored here.
254 * Construct a PrettySExprs with the given setting.
256 PrettySExprs(bool prettySExprs
) : d_prettySExprs(prettySExprs
) {}
258 inline void applyPrettySExprs(std::ostream
& out
) {
259 out
.iword(s_iosIndex
) = d_prettySExprs
;
262 static inline bool getPrettySExprs(std::ostream
& out
) {
263 return out
.iword(s_iosIndex
);
266 static inline void setPrettySExprs(std::ostream
& out
, bool prettySExprs
) {
267 out
.iword(s_iosIndex
) = prettySExprs
;
271 * Set the pretty-sexprs state on the output stream for the current
272 * stack scope. This makes sure the old state is reset on the
273 * stream after normal OR exceptional exit from the scope, using the
278 bool d_oldPrettySExprs
;
281 inline Scope(std::ostream
& out
, bool prettySExprs
)
282 : d_out(out
), d_oldPrettySExprs(PrettySExprs::getPrettySExprs(out
)) {
283 PrettySExprs::setPrettySExprs(out
, prettySExprs
);
286 inline ~Scope() { PrettySExprs::setPrettySExprs(d_out
, d_oldPrettySExprs
); }
288 }; /* class PrettySExprs::Scope */
290 }; /* class PrettySExprs */
293 * Sets the default pretty-sexprs setting for an ostream. Use like this:
295 * // let out be an ostream, s an SExpr
296 * out << PrettySExprs(true) << s << endl;
298 * The setting stays permanently (until set again) with the stream.
300 std::ostream
& operator<<(std::ostream
& out
, PrettySExprs ps
);
302 } /* CVC4 namespace */
304 #endif /* CVC4__SEXPR_H */