1 /********************* */
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
10 ** See the file COPYING in the top-level source directory for licensing
13 ** A super-class for ANTLR-generated input language parsers
19 #include "antlr_input.h"
21 #include "bounded_token_buffer.h"
22 #include "bounded_token_factory.h"
23 #include "memory_mapped_input_buffer.h"
24 #include "parser_exception.h"
27 #include "expr/command.h"
28 #include "expr/type.h"
29 #include "parser/cvc/cvc_input.h"
30 #include "parser/smt/smt_input.h"
31 #include "parser/smt2/smt2_input.h"
32 #include "util/output.h"
33 #include "util/Assert.h"
37 using namespace CVC4::parser
;
38 using namespace CVC4::kind
;
43 AntlrInputStream::AntlrInputStream(std::string name
, pANTLR3_INPUT_STREAM input
) :
48 AntlrInputStream::~AntlrInputStream() {
49 d_input
->free(d_input
);
52 pANTLR3_INPUT_STREAM
AntlrInputStream::getAntlr3InputStream() const {
56 AntlrInputStream
* AntlrInputStream::newFileInputStream(const std::string
& name
, bool useMmap
) {
58 return new AntlrInputStream( name
, MemoryMappedInputBufferNew(name
) );
60 return new AntlrInputStream( name
, antlr3AsciiFileStreamNew((pANTLR3_UINT8
) name
.c_str()) );
63 if( d_inputStream == NULL ) {
64 throw ParserException("Couldn't open file: " + filename);
69 AntlrInputStream
* AntlrInputStream::newStringInputStream(const std::string
& input
, const std::string
& name
) /*throw (InputStreamException) */{
70 char* inputStr
= strdup(input
.c_str());
71 char* nameStr
= strdup(name
.c_str());
73 if( inputStr==NULL || nameStr==NULL ) {
74 throw InputStreamException("Couldn't initialize string input: '" + input + "'");
77 return new AntlrInputStream( name
,
78 antlr3NewAsciiStringInPlaceStream(
79 (pANTLR3_UINT8
)inputStr
,input
.size(),
80 (pANTLR3_UINT8
)nameStr
) );
83 AntlrInput
* AntlrInput::newInput(InputLanguage lang
, AntlrInputStream
*inputStream
) {
88 input
= new CvcInput(inputStream
);
92 input
= new SmtInput(inputStream
);
96 input
= new Smt2Input(inputStream
);
105 AntlrInput::AntlrInput(AntlrInputStream
*inputStream
, unsigned int lookahead
) :
107 d_lookahead(lookahead
),
110 d_antlr3InputStream( inputStream
->getAntlr3InputStream() ),
111 d_tokenStream(NULL
) {
115 AntlrParser::AntlrParser(ExprManager* exprManager, std::istream& input, const std::string& name, unsigned int lookahead)
116 Parser(exprManager,name),
117 d_lookahead(lookahead) {
123 AntlrInput::Input(ExprManager* exprManager, const std::string& input, const std::string& name, unsigned int lookahead) :
124 Input(exprManager,name),
125 d_lookahead(lookahead),
128 d_tokenStream(NULL) {
130 char* inputStr = strdup(input.c_str());
131 char* nameStr = strdup(name.c_str());
132 if( inputStr==NULL || nameStr==NULL ) {
133 throw ParserException("Couldn't initialize string input: '" + input + "'");
135 d_inputStream = antlr3NewAsciiStringInPlaceStream((pANTLR3_UINT8)inputStr,input.size(),(pANTLR3_UINT8)nameStr);
136 if( d_inputStream == NULL ) {
137 throw ParserException("Couldn't create input stream for string: '" + input + "'");
143 AntlrInput::~AntlrInput() {
144 d_tokenStream
->free(d_tokenStream
);
147 pANTLR3_COMMON_TOKEN_STREAM
AntlrInput::getTokenStream() {
148 return d_tokenStream
;
151 void AntlrInput::lexerError(pANTLR3_BASE_RECOGNIZER recognizer
) {
152 pANTLR3_LEXER lexer
= (pANTLR3_LEXER
)(recognizer
->super
);
153 AlwaysAssert(lexer
!=NULL
);
154 Parser
*parser
= (Parser
*)(lexer
->super
);
155 AlwaysAssert(parser
!=NULL
);
156 AntlrInput
*input
= (AntlrInput
*) parser
->getInput();
157 AlwaysAssert(input
!=NULL
);
159 // Call the error display routine
160 input
->parseError("Error finding next token.");
163 void AntlrInput::parseError(const std::string
& message
)
164 throw (ParserException
) {
165 Debug("parser") << "Throwing exception: "
166 << getInputStream()->getName() << ":"
167 << d_lexer
->getLine(d_lexer
) << "."
168 << d_lexer
->getCharPositionInLine(d_lexer
) << ": "
170 throw ParserException(message
, getInputStream()->getName(),
171 d_lexer
->getLine(d_lexer
),
172 d_lexer
->getCharPositionInLine(d_lexer
));
176 void AntlrInput::setAntlr3Lexer(pANTLR3_LEXER pLexer
) {
179 pANTLR3_TOKEN_FACTORY pTokenFactory
= d_lexer
->rec
->state
->tokFactory
;
180 if( pTokenFactory
!= NULL
) {
181 pTokenFactory
->close(pTokenFactory
);
184 /* 2*lookahead should be sufficient, but we give ourselves some breathing room. */
185 pTokenFactory
= BoundedTokenFactoryNew(d_antlr3InputStream
, 2*d_lookahead
);
186 if( pTokenFactory
== NULL
) {
187 throw ParserException("Couldn't create token factory.");
189 d_lexer
->rec
->state
->tokFactory
= pTokenFactory
;
191 pBOUNDED_TOKEN_BUFFER buffer
= BoundedTokenBufferSourceNew(d_lookahead
, d_lexer
->rec
->state
->tokSource
);
192 if( buffer
== NULL
) {
193 throw ParserException("Couldn't create token buffer.");
196 d_tokenStream
= buffer
->commonTstream
;
198 // Override default lexer error reporting
199 d_lexer
->rec
->reportError
= &lexerError
;
202 void AntlrInput::setParser(Parser
*parser
) {
203 // ANTLR isn't using super in the lexer or the parser, AFAICT.
204 // We could also use @lexer/parser::context to add a field to the generated
205 // objects, but then it would have to be declared separately in every
206 // language's grammar and we'd have to in the address of the field anyway.
207 d_lexer
->super
= parser
;
208 d_parser
->super
= parser
;
212 void AntlrInput::setAntlr3Parser(pANTLR3_PARSER pParser
) {
214 // d_parser->rec->match = &match;
215 d_parser
->rec
->reportError
= &reportError
;
216 /* Don't try to recover from a parse error. */
217 // [chris 4/5/2010] Not clear on why this cast is necessary, but I get an error if I remove it.
218 d_parser
->rec
->recoverFromMismatchedToken
=
219 (void* (*)(ANTLR3_BASE_RECOGNIZER_struct
*, ANTLR3_UINT32
, ANTLR3_BITSET_LIST_struct
*))
220 d_parser
->rec
->mismatch
;
224 }/* CVC4::parser namespace */
225 }/* CVC4 namespace */