bin_PROGRAMS = cvc4
cvc4_SOURCES = \
- main.cpp \
getopt.cpp \
- util.cpp \
+ interactive_shell.h \
+ interactive_shell.cpp \
main.h \
- usage.h
+ main.cpp \
+ usage.h \
+ util.cpp
cvc4_LDADD = \
../parser/libcvc4parser.la \
--- /dev/null
+/********************* */
+/*! \file interactive_shell.cpp
+ ** \verbatim
+ ** Original author: cconway
+ ** Major contributors:
+ ** Minor contributors (to current version):
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Interactive shell for CVC4
+ **/
+
+#include <iostream>
+
+#include "interactive_shell.h"
+#include "expr/command.h"
+#include "parser/parser.h"
+#include "parser/parser_builder.h"
+
+using namespace std;
+
+namespace CVC4 {
+
+Command* InteractiveShell::readCommand() {
+ /* Don't do anything if the input is closed. */
+ if( d_in.eof() ) {
+ return NULL;
+ }
+
+ /* If something's wrong with the input, there's nothing we can do. */
+ if( !d_in.good() ) {
+ throw ParserException("Interactive input broken.");
+ }
+
+ string input;
+
+ /* Prompt the user for input. */
+ d_out << "CVC4> " << flush;
+ while(true) {
+ stringbuf sb;
+ string line;
+
+ /* Read a line */
+ d_in.get(sb,'\n');
+ line = sb.str();
+ // cout << "Input was '" << input << "'" << endl << flush;
+
+ /* If we hit EOF, we're done. */
+ if( d_in.eof() ) {
+ input += line;
+ break;
+ }
+
+ /* Check for failure */
+ if( d_in.fail() ) {
+ /* This should only happen if the input line was empty. */
+ Assert( line.empty() );
+ d_in.clear();
+ }
+
+ /* Extract the newline delimiter from the stream too */
+ int c = d_in.get();
+ Assert( c == '\n' );
+
+ // cout << "Next char is '" << (char)c << "'" << endl << flush;
+
+ /* Strip trailing whitespace. */
+ int n = line.length() - 1;
+ while( !line.empty() && isspace(line[n]) ) {
+ line.erase(n,1);
+ n--;
+ }
+
+ input += line;
+
+ /* If the last char was a backslash, continue on the next line. */
+ if( !line.empty() && line[n] == '\\' ) {
+ n = input.length() - 1;
+ Assert( input[n] == '\\' );
+ input[n] = '\n';
+ d_out << "... > " << flush;
+ } else {
+ /* No continuation, we're done. */
+ //cout << "Leaving input loop." << endl << flush;
+ break;
+ }
+ }
+
+ Parser *parser =
+ d_parserBuilder
+ .withStringInput(input)
+ .build();
+
+ /* There may be more than one command in the input. Build up a
+ sequence. */
+ CommandSequence *cmd_seq = new CommandSequence();
+ Command *cmd;
+
+ while( (cmd = parser->nextCommand()) ) {
+ cmd_seq->addCommand(cmd);
+ }
+
+ delete parser;
+ return cmd_seq;
+}
+
+} // CVC4 namespace
--- /dev/null
+/********************* */
+/*! \file interactive_shell.h
+ ** \verbatim
+ ** Original author: cconway
+ ** Major contributors:
+ ** Minor contributors (to current version):
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Interactive shell for CVC4
+ **/
+
+#ifndef __CVC4__INTERACTIVE_SHELL_H
+#define __CVC4__INTERACTIVE_SHELL_H
+
+#include <iostream>
+#include <string>
+
+#include "parser/parser_builder.h"
+
+namespace CVC4 {
+
+ class Command;
+
+ using namespace parser;
+
+class InteractiveShell {
+ std::istream& d_in;
+ std::ostream& d_out;
+ ParserBuilder d_parserBuilder;
+
+public:
+ InteractiveShell(std::istream& in,
+ std::ostream& out,
+ ParserBuilder& parserBuilder) :
+ d_in(in),
+ d_out(out),
+ d_parserBuilder(parserBuilder) {
+ }
+
+ /** Read a command from the interactive shell. This will read as
+ many lines as necessary to parse a well-formed command. */
+ Command *readCommand();
+};
+
+} // CVC4 namespace
+
+#endif // __CVC4__INTERACTIVE_SHELL_H
#include "cvc4autoconfig.h"
#include "main.h"
+#include "interactive_shell.h"
#include "usage.h"
#include "parser/parser.h"
#include "parser/parser_builder.h"
+#include "parser/parser_exception.h"
#include "expr/expr_manager.h"
#include "smt/smt_engine.h"
#include "expr/command.h"
firstArgIndex >= argc || !strcmp("-", argv[firstArgIndex]);
// if we're reading from stdin, default to interactive mode
- if(!options.interactiveSetByUser) {
- options.interactive = inputFromStdin;
- }
+ // [chris 10/20/10] The expected behavior of interactive is
+ // different from the expected behavior of file input from
+ // stdin, due to EOL escapes in interactive mode
+
+ // if(!options.interactiveSetByUser) {
+ // options.interactive = inputFromStdin;
+ // }
// Create the expression manager
ExprManager exprMgr(options.earlyTypeChecking);
parserBuilder.withStreamInput(cin);
}
- Parser *parser = parserBuilder.build();
-
// Parse and execute commands until we are done
Command* cmd;
if( options.interactive ) {
- // cout << "CVC4> " << flush;
- }
- while((cmd = parser->nextCommand())) {
- if( !options.parseOnly ) {
+ InteractiveShell shell(cin,cout,parserBuilder);
+ while((cmd = shell.readCommand())) {
+ doCommand(smt,cmd);
+ delete cmd;
+ }
+ } else {
+ Parser *parser = parserBuilder.build();
+ while((cmd = parser->nextCommand())) {
doCommand(smt, cmd);
+ delete cmd;
}
- delete cmd;
+ // Remove the parser
+ delete parser;
}
string result = smt.getInfo(":status").getValue();
exit(returnValue);
#endif
- // Remove the parser
- delete parser;
-
ReferenceStat< Result > s_statSatResult("sat/unsat", result);
StatisticsRegistry::registerStat(&s_statSatResult);
return returnValue;
}
+/** Executes a command. Deletes the command after execution. */
void doCommand(SmtEngine& smt, Command* cmd) {
+ if( options.parseOnly ) {
+ return;
+ }
+
CommandSequence *seq = dynamic_cast<CommandSequence*>(cmd);
if(seq != NULL) {
for(CommandSequence::iterator subcmd = seq->begin();
/** Get a bitvector constant from the text of the number and the size token */
static BitVector tokenToBitvector(pANTLR3_COMMON_TOKEN number, pANTLR3_COMMON_TOKEN size);
+ std::string getUnparsedText();
+
protected:
/** Create an input. This input takes ownership of the given input stream,
* and will delete it at destruction time.
virtual void setParser(Parser& parser);
};
+inline std::string AntlrInput::getUnparsedText() {
+ const char *base = (const char *)d_antlr3InputStream->data;
+ const char *cur = (const char *)d_antlr3InputStream->nextChar;
+
+ return std::string(cur, d_antlr3InputStream->sizeBuf - (cur - base));
+}
+
+
inline std::string AntlrInput::tokenText(pANTLR3_COMMON_TOKEN token) {
ANTLR3_MARKER start = token->getStartIndex(token);
ANTLR3_MARKER end = token->getStopIndex(token);
#include "antlr_input.h"
#include "parser.h"
+#include "parser_exception.h"
#include "util/Assert.h"
using namespace std;
pANTLR3_UINT8 * tokenNames = recognizer->state->tokenNames;
stringstream ss;
+ // Dig the CVC4 objects out of the ANTLR3 mess
+ pANTLR3_PARSER antlr3Parser = (pANTLR3_PARSER)(recognizer->super);
+ AlwaysAssert(antlr3Parser!=NULL);
+ Parser *parser = (Parser*)(antlr3Parser->super);
+ AlwaysAssert(parser!=NULL);
+ AntlrInput *input = (AntlrInput*) parser->getInput() ;
+ AlwaysAssert(input!=NULL);
+
// Signal we are in error recovery now
recognizer->state->errorRecovery = ANTLR3_TRUE;
break;
}
- // Now get ready to throw an exception
- pANTLR3_PARSER antlr3Parser = (pANTLR3_PARSER)(recognizer->super);
- AlwaysAssert(antlr3Parser!=NULL);
- Parser *parser = (Parser*)(antlr3Parser->super);
- AlwaysAssert(parser!=NULL);
- AntlrInput *input = (AntlrInput*) parser->getInput() ;
- AlwaysAssert(input!=NULL);
-
// Call the error display routine
input->parseError(ss.str());
}
virtual ~InputStreamException() throw() { }
};
-/** Wrapper around an ANTLR3 input stream. */
+/** Wrapper around an input stream. */
class InputStream {
/** The name of this input stream. */
/** The input stream. */
InputStream *d_inputStream;
- /* Since we own d_tokenStream and it needs to be freed, we need to prevent
+ /* Since we own d_inputStream and it needs to be freed, we need to prevent
* copy construction and assignment.
*/
Input(const Input& input) { Unimplemented("Copy constructor for Input."); }
public:
- /** Destructor. Frees the token stream and closes the input. */
+ /** Destructor. Frees the input stream and closes the input. */
virtual ~Input();
+ /** Retrieve the remaining text in this input. */
+ virtual std::string getUnparsedText() = 0;
+
protected:
/** Create an input.
return d_input;
}
- /** Set the declaration scope manager for this input. NOTE: This should <em>only</me> be
- * called before parsing begins. Otherwise, previous declarations will be lost. */
-/* inline void setDeclarationScope(DeclarationScope declScope) {
- d_declScope = declScope;
- }*/
-
/**
* Check if we are done -- either the end of input has been reached, or some
* error has been encountered.
/** Enable strict parsing, according to the language standards. */
void enableStrictMode() { d_strictMode = true; }
- /** Disable strict parsing. Allows certain syntactic infelicities to pass without comment. */
+ /** Disable strict parsing. Allows certain syntactic infelicities to
+ pass without comment. */
void disableStrictMode() { d_strictMode = false; }
bool strictModeEnabled() { return d_strictMode; }
default:
Unreachable();
}
+
+ Parser *parser = NULL;
switch(d_lang) {
case language::input::LANG_SMTLIB:
- return new Smt(&d_exprManager, input, d_strictMode);
+ parser = new Smt(&d_exprManager, input, d_strictMode);
case language::input::LANG_SMTLIB_V2:
- return new Smt2(&d_exprManager, input, d_strictMode);
+ parser = new Smt2(&d_exprManager, input, d_strictMode);
default:
- return new Parser(&d_exprManager, input, d_strictMode);
+ parser = new Parser(&d_exprManager, input, d_strictMode);
}
-}
-
-/*ParserBuilder& ParserBuilder::disableChecks() {
- d_checksEnabled = false;
- return *this;
-}
-ParserBuilder& ParserBuilder::disableMmap() {
- d_mmap = false;
- return *this;
-}
-
-ParserBuilder& ParserBuilder::disableStrictMode() {
- d_strictMode = false;
- return *this;
+ return parser;
}
-ParserBuilder& ParserBuilder::enableChecks() {
- d_checksEnabled = true;
- return *this;
-}
-
-ParserBuilder& ParserBuilder::enableMmap() {
- d_mmap = true;
- return *this;
-}
-
-ParserBuilder& ParserBuilder::enableStrictMode() {
- d_strictMode = true;
- return *this;
-}*/
-
ParserBuilder& ParserBuilder::withChecks(bool flag) {
d_checksEnabled = flag;
return *this;