GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/parser/parser.h Lines: 23 33 69.7 %
Date: 2021-09-07 Branches: 1 6 16.7 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Morgan Deters, Christopher L. Conway
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 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.
11
 * ****************************************************************************
12
 *
13
 * A collection of state for use by parser implementations.
14
 */
15
16
#include "cvc5parser_public.h"
17
18
#ifndef CVC5__PARSER__PARSER_H
19
#define CVC5__PARSER__PARSER_H
20
21
#include <list>
22
#include <memory>
23
#include <set>
24
#include <string>
25
26
#include "api/cpp/cvc5.h"
27
#include "cvc5_export.h"
28
#include "expr/kind.h"
29
#include "expr/symbol_manager.h"
30
#include "expr/symbol_table.h"
31
#include "parser/input.h"
32
#include "parser/parse_op.h"
33
#include "parser/parser_exception.h"
34
#include "util/unsafe_interrupt_exception.h"
35
36
namespace cvc5 {
37
38
// Forward declarations
39
class Command;
40
class ResourceManager;
41
42
namespace parser {
43
44
class Input;
45
46
/** Types of checks for the symbols */
47
enum DeclarationCheck {
48
  /** Enforce that the symbol has been declared */
49
  CHECK_DECLARED,
50
  /** Enforce that the symbol has not been declared */
51
  CHECK_UNDECLARED,
52
  /** Don't check anything */
53
  CHECK_NONE
54
};/* enum DeclarationCheck */
55
56
/**
57
 * Returns a string representation of the given object (for
58
 * debugging).
59
 */
60
inline std::ostream& operator<<(std::ostream& out, DeclarationCheck check);
61
inline std::ostream& operator<<(std::ostream& out, DeclarationCheck check) {
62
  switch(check) {
63
  case CHECK_NONE:
64
    return out << "CHECK_NONE";
65
  case CHECK_DECLARED:
66
    return out << "CHECK_DECLARED";
67
  case CHECK_UNDECLARED:
68
    return out << "CHECK_UNDECLARED";
69
  default:
70
    return out << "DeclarationCheck!UNKNOWN";
71
  }
72
}
73
74
/**
75
 * Types of symbols. Used to define namespaces.
76
 */
77
enum SymbolType {
78
  /** Variables */
79
  SYM_VARIABLE,
80
  /** Sorts */
81
  SYM_SORT
82
};/* enum SymbolType */
83
84
/**
85
 * Returns a string representation of the given object (for
86
 * debugging).
87
 */
88
inline std::ostream& operator<<(std::ostream& out, SymbolType type);
89
inline std::ostream& operator<<(std::ostream& out, SymbolType type) {
90
  switch(type) {
91
  case SYM_VARIABLE:
92
    return out << "SYM_VARIABLE";
93
  case SYM_SORT:
94
    return out << "SYM_SORT";
95
  default:
96
    return out << "SymbolType!UNKNOWN";
97
  }
98
}
99
100
/**
101
 * This class encapsulates all of the state of a parser, including the
102
 * name of the file, line number and column information, and in-scope
103
 * declarations.
104
 */
105
class CVC5_EXPORT Parser
106
{
107
  friend class ParserBuilder;
108
private:
109
110
 /** The input that we're parsing. */
111
 std::unique_ptr<Input> d_input;
112
113
 /**
114
  * Reference to the symbol manager, which manages the symbol table used by
115
  * this parser.
116
  */
117
 SymbolManager* d_symman;
118
119
 /**
120
  * This current symbol table used by this parser, from symbol manager.
121
  */
122
 SymbolTable* d_symtab;
123
124
 /**
125
  * The level of the assertions in the declaration scope.  Things declared
126
  * after this level are bindings from e.g. a let, a quantifier, or a
127
  * lambda.
128
  */
129
 size_t d_assertionLevel;
130
131
 /** How many anonymous functions we've created. */
132
 size_t d_anonymousFunctionCount;
133
134
 /** Are we done */
135
 bool d_done;
136
137
 /** Are semantic checks enabled during parsing? */
138
 bool d_checksEnabled;
139
140
 /** Are we parsing in strict mode? */
141
 bool d_strictMode;
142
143
 /** Are we only parsing? */
144
 bool d_parseOnly;
145
146
 /**
147
  * Can we include files?  (Set to false for security purposes in
148
  * e.g. the online version.)
149
  */
150
 bool d_canIncludeFile;
151
152
 /**
153
  * Whether the logic has been forced with --force-logic.
154
  */
155
 bool d_logicIsForced;
156
157
 /**
158
  * The logic, if d_logicIsForced == true.
159
  */
160
 std::string d_forcedLogic;
161
162
 /** The set of operators available in the current logic. */
163
 std::set<api::Kind> d_logicOperators;
164
165
 /** The set of attributes already warned about. */
166
 std::set<std::string> d_attributesWarnedAbout;
167
168
 /**
169
  * The current set of unresolved types.  We can get by with this NOT
170
  * being on the scope, because we can only have one DATATYPE
171
  * definition going on at one time.  This is a bit hackish; we
172
  * depend on mkMutualDatatypeTypes() to check everything and clear
173
  * this out.
174
  */
175
 std::set<api::Sort> d_unresolved;
176
177
 /**
178
  * "Preemption commands": extra commands implied by subterms that
179
  * should be issued before the currently-being-parsed command is
180
  * issued.  Used to support SMT-LIBv2 ":named" attribute on terms.
181
  *
182
  * Owns the memory of the Commands in the queue.
183
  */
184
 std::list<Command*> d_commandQueue;
185
186
 /** Lookup a symbol in the given namespace (as specified by the type).
187
  * Only returns a symbol if it is not overloaded, returns null otherwise.
188
  */
189
 api::Term getSymbol(const std::string& var_name, SymbolType type);
190
191
protected:
192
 /** The API Solver object. */
193
 api::Solver* d_solver;
194
195
 /**
196
  * Create a parser state.
197
  *
198
  * @attention The parser takes "ownership" of the given
199
  * input and will delete it on destruction.
200
  *
201
  * @param solver solver API object
202
  * @param symm reference to the symbol manager
203
  * @param input the parser input
204
  * @param strictMode whether to incorporate strict(er) compliance checks
205
  * @param parseOnly whether we are parsing only (and therefore certain checks
206
  * need not be performed, like those about unimplemented features, @see
207
  * unimplementedFeature())
208
  */
209
 Parser(api::Solver* solver,
210
        SymbolManager* sm,
211
        bool strictMode = false,
212
        bool parseOnly = false);
213
214
public:
215
216
  virtual ~Parser();
217
218
  /** Get the associated solver. */
219
  api::Solver* getSolver() const;
220
221
  /** Get the associated input. */
222
96
  Input* getInput() const { return d_input.get(); }
223
224
  /** Get unresolved sorts */
225
  inline std::set<api::Sort>& getUnresolvedSorts() { return d_unresolved; }
226
227
  /** Deletes and replaces the current parser input. */
228
6455
  void setInput(Input* input)  {
229
6455
    d_input.reset(input);
230
6455
    d_input->setParser(*this);
231
6455
    d_done = false;
232
6455
  }
233
234
  /**
235
   * Check if we are done -- either the end of input has been reached, or some
236
   * error has been encountered.
237
   * @return true if parser is done
238
   */
239
488
  inline bool done() const {
240
488
    return d_done;
241
  }
242
243
  /** Sets the done flag */
244
296180
  inline void setDone(bool done = true) {
245
296180
    d_done = done;
246
296180
  }
247
248
  /** Enable semantic checks during parsing. */
249
6427
  void enableChecks() { d_checksEnabled = true; }
250
251
  /** Disable semantic checks during parsing. Disabling checks may lead to crashes on bad inputs. */
252
  void disableChecks() { d_checksEnabled = false; }
253
254
  /** Enable strict parsing, according to the language standards. */
255
  void enableStrictMode() { d_strictMode = true; }
256
257
  /** Disable strict parsing. Allows certain syntactic infelicities to
258
      pass without comment. */
259
  void disableStrictMode() { d_strictMode = false; }
260
261
4090630
  bool strictModeEnabled() { return d_strictMode; }
262
263
6427
  void allowIncludeFile() { d_canIncludeFile = true; }
264
  void disallowIncludeFile() { d_canIncludeFile = false; }
265
7
  bool canIncludeFile() const { return d_canIncludeFile; }
266
267
  /** Expose the functionality from SMT/SMT2 parsers, while making
268
      implementation optional by returning false by default. */
269
  virtual bool logicIsSet() { return false; }
270
271
  virtual void forceLogic(const std::string& logic);
272
273
8
  const std::string& getForcedLogic() const { return d_forcedLogic; }
274
5423
  bool logicIsForced() const { return d_logicIsForced; }
275
276
  /**
277
   * Gets the variable currently bound to name.
278
   *
279
   * @param name the name of the variable
280
   * @return the variable expression
281
   * Only returns a variable if its name is not overloaded, returns null otherwise.
282
   */
283
  api::Term getVariable(const std::string& name);
284
285
  /**
286
   * Gets the function currently bound to name.
287
   *
288
   * @param name the name of the variable
289
   * @return the variable expression
290
   * Only returns a function if its name is not overloaded, returns null otherwise.
291
   */
292
  api::Term getFunction(const std::string& name);
293
294
  /**
295
   * Returns the expression that name should be interpreted as, based on the current binding.
296
   *
297
   * The symbol name should be declared.
298
   * This creates the expression that the string "name" should be interpreted as.
299
   * Typically this corresponds to a variable, but it may also correspond to
300
   * a nullary constructor or a defined function.
301
   * Only returns an expression if its name is not overloaded, returns null otherwise.
302
   */
303
  virtual api::Term getExpressionForName(const std::string& name);
304
305
  /**
306
   * Returns the expression that name should be interpreted as, based on the
307
   * current binding.
308
   *
309
   * This is the same as above but where the name has been type cast to t.
310
   */
311
  virtual api::Term getExpressionForNameAndType(const std::string& name,
312
                                                api::Sort t);
313
314
  /**
315
   * If this method returns true, then name is updated with the tester name
316
   * for constructor cons.
317
   *
318
   * In detail, notice that (user-defined) datatypes associate a unary predicate
319
   * for each constructor, called its "tester". This symbol is automatically
320
   * defined when a datatype is defined. The tester name for a constructor
321
   * (e.g. "cons") depends on the language:
322
   * - In smt versions < 2.6, the (non-standard) syntax is "is-cons",
323
   * - In smt versions >= 2.6, the indexed symbol "(_ is cons)" is used. Thus,
324
   * no tester symbol is necessary, since "is" is a builtin symbol. We still use
325
   * the above syntax if strict mode is disabled.
326
   * - In cvc, the syntax for testers is "is_cons".
327
   */
328
  virtual bool getTesterName(api::Term cons, std::string& name);
329
330
  /**
331
   * Returns the kind that should be used for applications of expression fun.
332
   * This is a generalization of ExprManager::operatorToKind that also
333
   * handles variables whose types are "function-like", i.e. where
334
   * checkFunctionLike(fun) returns true.
335
   *
336
   * For examples of the latter, this function returns
337
   *   APPLY_UF if fun has function type,
338
   *   APPLY_CONSTRUCTOR if fun has constructor type.
339
   */
340
  api::Kind getKindForFunction(api::Term fun);
341
342
  /**
343
   * Returns a sort, given a name.
344
   * @param sort_name the name to look up
345
   */
346
  api::Sort getSort(const std::string& sort_name);
347
348
  /**
349
   * Returns a (parameterized) sort, given a name and args.
350
   */
351
  api::Sort getSort(const std::string& sort_name,
352
                    const std::vector<api::Sort>& params);
353
354
  /**
355
   * Returns arity of a (parameterized) sort, given a name and args.
356
   */
357
  size_t getArity(const std::string& sort_name);
358
359
  /**
360
   * Checks if a symbol has been declared.
361
   * @param name the symbol name
362
   * @param type the symbol type
363
   * @return true iff the symbol has been declared with the given type
364
   */
365
  bool isDeclared(const std::string& name, SymbolType type = SYM_VARIABLE);
366
367
  /**
368
   * Checks if the declaration policy we want to enforce holds
369
   * for the given symbol.
370
   * @param name the symbol to check
371
   * @param check the kind of check to perform
372
   * @param type the type of the symbol
373
   * @param notes notes to add to a parse error (if one is generated)
374
   * @throws ParserException if checks are enabled and the check fails
375
   */
376
  void checkDeclaration(const std::string& name,
377
                        DeclarationCheck check,
378
                        SymbolType type = SYM_VARIABLE,
379
                        std::string notes = "");
380
381
  /**
382
   * Checks whether the given expression is function-like, i.e.
383
   * it expects arguments. This is checked by looking at the type
384
   * of fun. Examples of function types are function, constructor,
385
   * selector, tester.
386
   * @param fun the expression to check
387
   * @throws ParserException if checks are enabled and fun is not
388
   * a function
389
   */
390
  void checkFunctionLike(api::Term fun);
391
392
  /** Create a new cvc5 variable expression of the given type.
393
   *
394
   * It is inserted at context level zero in the symbol table if levelZero is
395
   * true, or if we are using global declarations.
396
   *
397
   * If a symbol with name already exists,
398
   *  then if doOverload is true, we create overloaded operators.
399
   *  else if doOverload is false, the existing expression is shadowed by the
400
   * new expression.
401
   */
402
  api::Term bindVar(const std::string& name,
403
                    const api::Sort& type,
404
                    bool levelZero = false,
405
                    bool doOverload = false);
406
407
  /**
408
   * Create a set of new cvc5 variable expressions of the given type.
409
   *
410
   * It is inserted at context level zero in the symbol table if levelZero is
411
   * true, or if we are using global declarations.
412
   *
413
   * For each name, if a symbol with name already exists,
414
   *  then if doOverload is true, we create overloaded operators.
415
   *  else if doOverload is false, the existing expression is shadowed by the
416
   * new expression.
417
   */
418
  std::vector<api::Term> bindVars(const std::vector<std::string> names,
419
                                  const api::Sort& type,
420
                                  bool levelZero = false,
421
                                  bool doOverload = false);
422
423
  /**
424
   * Create a new cvc5 bound variable expression of the given type. This binds
425
   * the symbol name to that variable in the current scope.
426
   */
427
  api::Term bindBoundVar(const std::string& name, const api::Sort& type);
428
  /**
429
   * Create a new cvc5 bound variable expressions of the given names and types.
430
   * Like the method above, this binds these names to those variables in the
431
   * current scope.
432
   */
433
  std::vector<api::Term> bindBoundVars(
434
      std::vector<std::pair<std::string, api::Sort> >& sortedVarNames);
435
436
  /**
437
   * Create a set of new cvc5 bound variable expressions of the given type.
438
   *
439
   * For each name, if a symbol with name already exists,
440
   *  then if doOverload is true, we create overloaded operators.
441
   *  else if doOverload is false, the existing expression is shadowed by the
442
   * new expression.
443
   */
444
  std::vector<api::Term> bindBoundVars(const std::vector<std::string> names,
445
                                       const api::Sort& type);
446
447
  /** Create a new variable definition (e.g., from a let binding).
448
   * levelZero is set if the binding must be done at level 0.
449
   * If a symbol with name already exists,
450
   *  then if doOverload is true, we create overloaded operators.
451
   *  else if doOverload is false, the existing expression is shadowed by the
452
   * new expression.
453
   */
454
  void defineVar(const std::string& name,
455
                 const api::Term& val,
456
                 bool levelZero = false,
457
                 bool doOverload = false);
458
459
  /**
460
   * Create a new type definition.
461
   *
462
   * @param name The name of the type
463
   * @param type The type that should be associated with the name
464
   * @param levelZero If true, the type definition is considered global and
465
   *                  cannot be removed by popping the user context
466
   * @param skipExisting If true, the type definition is ignored if the same
467
   *                     symbol has already been defined. It is assumed that
468
   *                     the definition is the exact same as the existing one.
469
   */
470
  void defineType(const std::string& name,
471
                  const api::Sort& type,
472
                  bool levelZero = false,
473
                  bool skipExisting = false);
474
475
  /**
476
   * Create a new (parameterized) type definition.
477
   *
478
   * @param name The name of the type
479
   * @param params The type parameters
480
   * @param type The type that should be associated with the name
481
   * @param levelZero If true, the type definition is considered global and
482
   *                  cannot be removed by poppoing the user context
483
   */
484
  void defineType(const std::string& name,
485
                  const std::vector<api::Sort>& params,
486
                  const api::Sort& type,
487
                  bool levelZero = false);
488
489
  /** Create a new type definition (e.g., from an SMT-LIBv2 define-sort). */
490
  void defineParameterizedType(const std::string& name,
491
                               const std::vector<api::Sort>& params,
492
                               const api::Sort& type);
493
494
  /**
495
   * Creates a new sort with the given name.
496
   */
497
  api::Sort mkSort(const std::string& name);
498
499
  /**
500
   * Creates a new sort constructor with the given name and arity.
501
   */
502
  api::Sort mkSortConstructor(const std::string& name, size_t arity);
503
504
  /**
505
   * Creates a new "unresolved type," used only during parsing.
506
   */
507
  api::Sort mkUnresolvedType(const std::string& name);
508
509
  /**
510
   * Creates a new unresolved (parameterized) type constructor of the given
511
   * arity.
512
   */
513
  api::Sort mkUnresolvedTypeConstructor(const std::string& name, size_t arity);
514
  /**
515
   * Creates a new unresolved (parameterized) type constructor given the type
516
   * parameters.
517
   */
518
  api::Sort mkUnresolvedTypeConstructor(const std::string& name,
519
                                        const std::vector<api::Sort>& params);
520
521
  /**
522
   * Creates a new unresolved (parameterized) type constructor of the given
523
   * arity. Calls either mkUnresolvedType or mkUnresolvedTypeConstructor
524
   * depending on the arity.
525
   */
526
  api::Sort mkUnresolvedType(const std::string& name, size_t arity);
527
528
  /**
529
   * Returns true IFF name is an unresolved type.
530
   */
531
  bool isUnresolvedType(const std::string& name);
532
533
  /**
534
   * Creates and binds sorts of a list of mutually-recursive datatype
535
   * declarations.
536
   *
537
   * For each symbol defined by the datatype, if a symbol with name already
538
   * exists, then if doOverload is true, we create overloaded operators. Else, if
539
   * doOverload is false, the existing expression is shadowed by the new
540
   * expression.
541
   */
542
  std::vector<api::Sort> bindMutualDatatypeTypes(
543
      std::vector<api::DatatypeDecl>& datatypes, bool doOverload = false);
544
545
  /** make flat function type
546
   *
547
   * Returns the "flat" function type corresponding to the function taking
548
   * argument types "sorts" and range type "range".  A flat function type is
549
   * one whose range is not a function. Notice that if sorts is empty and range
550
   * is not a function, then this function returns range itself.
551
   *
552
   * If range is a function type, we add its function argument sorts to sorts
553
   * and consider its function range as the new range. For each sort S added
554
   * to sorts in this process, we add a new bound variable of sort S to
555
   * flattenVars.
556
   *
557
   * For example:
558
   * mkFlattenFunctionType( { Int, (-> Real Real) }, (-> Int Bool), {} ):
559
   * - returns the the function type (-> Int (-> Real Real) Int Bool)
560
   * - updates sorts to { Int, (-> Real Real), Int },
561
   * - updates flattenVars to { x }, where x is bound variable of type Int.
562
   *
563
   * Notice that this method performs only one level of flattening, for example,
564
   * mkFlattenFunctionType({ Int, (-> Real Real) }, (-> Int (-> Int Bool)), {}):
565
   * - returns the the function type (-> Int (-> Real Real) Int (-> Int Bool))
566
   * - updates sorts to { Int, (-> Real Real), Int },
567
   * - updates flattenVars to { x }, where x is bound variable of type Int.
568
   *
569
   * This method is required so that we do not return functions
570
   * that have function return type (these give an unhandled exception
571
   * in the ExprManager). For examples of the equivalence between function
572
   * definitions in the proposed higher-order extension of the smt2 language,
573
   * see page 3 of http://matryoshka.gforge.inria.fr/pubs/PxTP2017.pdf.
574
   *
575
   * The argument flattenVars is needed in the case of defined functions
576
   * with function return type. These have implicit arguments, for instance:
577
   *    (define-fun Q ((x Int)) (-> Int Int) (lambda y (P x)))
578
   * is equivalent to the command:
579
   *    (define-fun Q ((x Int) (z Int)) Int (@ (lambda y (P x)) z))
580
   * where @ is (higher-order) application. In this example, z is added to
581
   * flattenVars.
582
   */
583
  api::Sort mkFlatFunctionType(std::vector<api::Sort>& sorts,
584
                               api::Sort range,
585
                               std::vector<api::Term>& flattenVars);
586
587
  /** make flat function type
588
   *
589
   * Same as above, but does not take argument flattenVars.
590
   * This is used when the arguments of the function are not important (for
591
   * instance, if we are only using this type in a declare-fun).
592
   */
593
  api::Sort mkFlatFunctionType(std::vector<api::Sort>& sorts, api::Sort range);
594
595
  /** make higher-order apply
596
   *
597
   * This returns the left-associative curried application of (function) expr to
598
   * the arguments in args.
599
   *
600
   * For example, mkHoApply( f, { a, b }, 0 ) returns
601
   *  (HO_APPLY (HO_APPLY f a) b)
602
   *
603
   * If args is non-empty, the expected type of expr is (-> T0 ... Tn T), where
604
   *    args[i].getType() = Ti
605
   * for each i where 0 <= i < args.size(). If expr is not of this
606
   * type, the expression returned by this method will not be well typed.
607
   */
608
  api::Term mkHoApply(api::Term expr, const std::vector<api::Term>& args);
609
610
  /** Apply type ascription
611
   *
612
   * Return term t with a type ascription applied to it. This is used for
613
   * syntax like (as t T) in smt2 and t::T in the CVC language. This includes:
614
   * - (as emptyset (Set T))
615
   * - (as emptybag (Bag T))
616
   * - (as univset (Set T))
617
   * - (as sep.nil T)
618
   * - (cons T)
619
   * - ((as cons T) t1 ... tn) where cons is a parametric datatype constructor.
620
   *
621
   * The term to ascribe t is a term whose kind and children (but not type)
622
   * are equivalent to that of the term returned by this method.
623
   *
624
   * Notice that method is not necessarily a cast. In actuality, the above terms
625
   * should be understood as symbols indexed by types. However, SMT-LIB does not
626
   * permit types as indices, so we must use, e.g. (as emptyset (Set T))
627
   * instead of (_ emptyset (Set T)).
628
   *
629
   * @param t The term to ascribe a type
630
   * @param s The sort to ascribe
631
   * @return Term t with sort s ascribed.
632
   */
633
  api::Term applyTypeAscription(api::Term t, api::Sort s);
634
635
  /**
636
   * Add an operator to the current legal set.
637
   *
638
   * @param kind the built-in operator to add
639
   */
640
  void addOperator(api::Kind kind);
641
642
  /**
643
   * Preempt the next returned command with other ones; used to
644
   * support the :named attribute in SMT-LIBv2, which implicitly
645
   * inserts a new command before the current one. Also used in TPTP
646
   * because function and predicate symbols are implicitly declared.
647
   */
648
  void preemptCommand(Command* cmd);
649
650
  /** Is the symbol bound to a boolean variable? */
651
  bool isBoolean(const std::string& name);
652
653
  /** Is fun a function (or function-like thing)?
654
   * Currently this means its type is either a function, constructor, tester, or
655
   * selector.
656
   */
657
  bool isFunctionLike(api::Term fun);
658
659
  /** Is the symbol bound to a predicate? */
660
  bool isPredicate(const std::string& name);
661
662
  /** Parse and return the next command. */
663
  Command* nextCommand();
664
665
  /** Parse and return the next expression. */
666
  api::Term nextExpression();
667
668
  /** Issue a warning to the user. */
669
273
  void warning(const std::string& msg) { d_input->warning(msg); }
670
  /** Issue a warning to the user, but only once per attribute. */
671
  void attributeNotSupported(const std::string& attr);
672
673
  /** Raise a parse error with the given message. */
674
73
  inline void parseError(const std::string& msg) { d_input->parseError(msg); }
675
  /** Unexpectedly encountered an EOF */
676
  inline void unexpectedEOF(const std::string& msg)
677
  {
678
    d_input->parseError(msg, true);
679
  }
680
681
  /**
682
   * If we are parsing only, don't raise an exception; if we are not,
683
   * raise a parse error with the given message.  There is no actual
684
   * parse error, everything is as expected, but we cannot create the
685
   * Expr, Type, or other requested thing yet due to internal
686
   * limitations.  Even though it's not a parse error, we throw a
687
   * parse error so that the input line and column information is
688
   * available.
689
   *
690
   * Think quantifiers.  We don't have a TheoryQuantifiers yet, so we
691
   * have no kind::FORALL or kind::EXISTS.  But we might want to
692
   * support parsing quantifiers (just not doing anything with them).
693
   * So this mechanism gives you a way to do it with --parse-only.
694
   */
695
  inline void unimplementedFeature(const std::string& msg)
696
  {
697
    if(!d_parseOnly) {
698
      parseError("Unimplemented feature: " + msg);
699
    }
700
  }
701
702
  /**
703
   * Gets the current declaration level.
704
   */
705
  size_t scopeLevel() const;
706
707
  /**
708
   * Pushes a scope. All subsequent symbol declarations made are only valid in
709
   * this scope, i.e. they are deleted on the next call to popScope.
710
   *
711
   * The argument isUserContext is true, when we are pushing a user context
712
   * e.g. via the smt2 command (push n). This may also include one initial
713
   * pushScope when the parser is initialized. User-context pushes and pops
714
   * have an impact on both expression names and the symbol table, whereas
715
   * other pushes and pops only have an impact on the symbol table.
716
   */
717
  void pushScope(bool isUserContext = false);
718
719
  void popScope();
720
721
  virtual void reset();
722
723
  /** Return the symbol manager used by this parser. */
724
  SymbolManager* getSymbolManager();
725
726
  //------------------------ operator overloading
727
  /** is this function overloaded? */
728
  bool isOverloadedFunction(api::Term fun)
729
  {
730
    return d_symtab->isOverloadedFunction(fun);
731
  }
732
733
  /** Get overloaded constant for type.
734
   * If possible, it returns a defined symbol with name
735
   * that has type t. Otherwise returns null expression.
736
  */
737
6
  api::Term getOverloadedConstantForType(const std::string& name, api::Sort t)
738
  {
739
6
    return d_symtab->getOverloadedConstantForType(name, t);
740
  }
741
742
  /**
743
   * If possible, returns a defined function for a name
744
   * and a vector of expected argument types. Otherwise returns
745
   * null expression.
746
   */
747
122
  api::Term getOverloadedFunctionForTypes(const std::string& name,
748
                                          std::vector<api::Sort>& argTypes)
749
  {
750
122
    return d_symtab->getOverloadedFunctionForTypes(name, argTypes);
751
  }
752
  //------------------------ end operator overloading
753
  /**
754
   * Make string constant
755
   *
756
   * This makes the string constant based on the string s. This may involve
757
   * processing ad-hoc escape sequences (if the language is not
758
   * SMT-LIB 2.6 or higher), or otherwise calling the solver to construct
759
   * the string.
760
   */
761
  api::Term mkStringConstant(const std::string& s);
762
763
  /**
764
   * Make string constant from a single character in hex representation
765
   *
766
   * This makes the string constant based on the character from the strings,
767
   * represented as a hexadecimal code point.
768
   */
769
  api::Term mkCharConstant(const std::string& s);
770
771
  /** ad-hoc string escaping
772
   *
773
   * Returns the (internal) vector of code points corresponding to processing
774
   * the escape sequences in string s. This is to support string inputs that
775
   * do no comply with the SMT-LIB standard.
776
   *
777
   * This method handles escape sequences, including \n, \t, \v, \b, \r, \f, \a,
778
   * \\, \x[N] and octal escape sequences of the form \[c1]([c2]([c3])?)? where
779
   * c1, c2, c3 are digits from 0 to 7.
780
   */
781
  std::wstring processAdHocStringEsc(const std::string& s);
782
}; /* class Parser */
783
784
}  // namespace parser
785
}  // namespace cvc5
786
787
#endif /* CVC5__PARSER__PARSER_STATE_H */