Adding Integer and Rational constants to SMT
[cvc5.git] / src / parser / antlr_input.cpp
1 /********************* */
2 /** antlr_input.cpp
3 ** Original author: cconway
4 ** Major contributors: none
5 ** Minor contributors (to current version): none
6 ** This file is part of the CVC4 prototype.
7 ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys)
8 ** Courant Institute of Mathematical Sciences
9 ** New York University
10 ** See the file COPYING in the top-level source directory for licensing
11 ** information.
12 **
13 ** A super-class for ANTLR-generated input language parsers
14 **/
15
16 #include <limits.h>
17 #include <antlr3.h>
18
19 #include "antlr_input.h"
20 #include "bounded_token_buffer.h"
21 #include "bounded_token_factory.h"
22 #include "memory_mapped_input_buffer.h"
23 #include "parser_exception.h"
24 #include "parser_state.h"
25
26 #include "util/output.h"
27 #include "util/Assert.h"
28 #include "expr/command.h"
29 #include "expr/type.h"
30
31 using namespace std;
32 using namespace CVC4;
33 using namespace CVC4::parser;
34 using namespace CVC4::kind;
35
36 namespace CVC4 {
37 namespace parser {
38
39 AntlrInput::AntlrInput(ExprManager* exprManager, const std::string& filename, unsigned int lookahead, bool useMmap) :
40 Input(exprManager, filename),
41 d_lookahead(lookahead),
42 d_lexer(NULL),
43 d_parser(NULL),
44 d_tokenStream(NULL) {
45
46 if( useMmap ) {
47 d_input = MemoryMappedInputBufferNew(filename);
48 } else {
49 d_input = antlr3AsciiFileStreamNew((pANTLR3_UINT8) filename.c_str());
50 }
51 if( d_input == NULL ) {
52 throw ParserException("Couldn't open file: " + filename);
53 }
54 }
55
56 /*
57 AntlrParser::AntlrParser(ExprManager* exprManager, std::istream& input, const std::string& name, unsigned int lookahead)
58 Parser(exprManager,name),
59 d_lookahead(lookahead) {
60
61 }
62 */
63
64 AntlrInput::AntlrInput(ExprManager* exprManager, const std::string& input, const std::string& name, unsigned int lookahead) :
65 Input(exprManager,name),
66 d_lookahead(lookahead),
67 d_lexer(NULL),
68 d_parser(NULL),
69 d_tokenStream(NULL) {
70 char* inputStr = strdup(input.c_str());
71 char* nameStr = strdup(name.c_str());
72 if( inputStr==NULL || nameStr==NULL ) {
73 throw ParserException("Couldn't initialize string input: '" + input + "'");
74 }
75 d_input = antlr3NewAsciiStringInPlaceStream((pANTLR3_UINT8)inputStr,input.size(),(pANTLR3_UINT8)nameStr);
76 if( d_input == NULL ) {
77 throw ParserException("Couldn't create input stream for string: '" + input + "'");
78 }
79 }
80
81 AntlrInput::~AntlrInput() {
82 d_tokenStream->free(d_tokenStream);
83 d_input->close(d_input);
84 }
85
86 pANTLR3_INPUT_STREAM AntlrInput::getInputStream() {
87 return d_input;
88 }
89
90 pANTLR3_COMMON_TOKEN_STREAM AntlrInput::getTokenStream() {
91 return d_tokenStream;
92 }
93
94 void AntlrInput::lexerError(pANTLR3_BASE_RECOGNIZER recognizer) {
95 pANTLR3_LEXER lexer = (pANTLR3_LEXER)(recognizer->super);
96 AlwaysAssert(lexer!=NULL);
97 ParserState *parserState = (ParserState*)(lexer->super);
98 AlwaysAssert(parserState!=NULL);
99
100 // Call the error display routine
101 parserState->parseError("Error finding next token.");
102 }
103
104 void AntlrInput::parseError(const std::string& message)
105 throw (ParserException) {
106 Debug("parser") << "Throwing exception: "
107 << getParserState()->getFilename() << ":"
108 << d_lexer->getLine(d_lexer) << "."
109 << d_lexer->getCharPositionInLine(d_lexer) << ": "
110 << message << endl;
111 throw ParserException(message, getParserState()->getFilename(),
112 d_lexer->getLine(d_lexer),
113 d_lexer->getCharPositionInLine(d_lexer));
114 }
115
116
117 void AntlrInput::setLexer(pANTLR3_LEXER pLexer) {
118 d_lexer = pLexer;
119
120 pANTLR3_TOKEN_FACTORY pTokenFactory = d_lexer->rec->state->tokFactory;
121 if( pTokenFactory != NULL ) {
122 pTokenFactory->close(pTokenFactory);
123 }
124
125 /* 2*lookahead should be sufficient, but we give ourselves some breathing room. */
126 pTokenFactory = BoundedTokenFactoryNew(d_input, 2*d_lookahead);
127 if( pTokenFactory == NULL ) {
128 throw ParserException("Couldn't create token factory.");
129 }
130 d_lexer->rec->state->tokFactory = pTokenFactory;
131
132 pBOUNDED_TOKEN_BUFFER buffer = BoundedTokenBufferSourceNew(d_lookahead, d_lexer->rec->state->tokSource);
133 if( buffer == NULL ) {
134 throw ParserException("Couldn't create token buffer.");
135 }
136
137 d_tokenStream = buffer->commonTstream;
138
139 // ANTLR isn't using super, AFAICT.
140 d_lexer->super = getParserState();
141 // Override default lexer error reporting
142 d_lexer->rec->reportError = &lexerError;
143 }
144
145 void AntlrInput::setParser(pANTLR3_PARSER pParser) {
146 d_parser = pParser;
147 // ANTLR isn't using super, AFAICT.
148 // We could also use @parser::context to add a field to the generated parser, but then
149 // it would have to be declared separately in every input's grammar and we'd have to
150 // pass it in as an address anyway.
151 d_parser->super = getParserState();
152 // d_parser->rec->match = &match;
153 d_parser->rec->reportError = &reportError;
154 /* Don't try to recover from a parse error. */
155 // [chris 4/5/2010] Not clear on why this cast is necessary, but I get an error if I remove it.
156 d_parser->rec->recoverFromMismatchedToken =
157 (void* (*)(ANTLR3_BASE_RECOGNIZER_struct*, ANTLR3_UINT32, ANTLR3_BITSET_LIST_struct*))
158 d_parser->rec->mismatch;
159 }
160
161
162 }/* CVC4::parser namespace */
163 }/* CVC4 namespace */