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"
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"
26 #include "util/output.h"
27 #include "util/Assert.h"
28 #include "expr/command.h"
29 #include "expr/type.h"
33 using namespace CVC4::parser
;
34 using namespace CVC4::kind
;
39 AntlrInput::AntlrInput(ExprManager
* exprManager
, const std::string
& filename
, unsigned int lookahead
, bool useMmap
) :
40 Input(exprManager
, filename
),
41 d_lookahead(lookahead
),
47 d_input
= MemoryMappedInputBufferNew(filename
);
49 d_input
= antlr3AsciiFileStreamNew((pANTLR3_UINT8
) filename
.c_str());
51 if( d_input
== NULL
) {
52 throw ParserException("Couldn't open file: " + filename
);
57 AntlrParser::AntlrParser(ExprManager* exprManager, std::istream& input, const std::string& name, unsigned int lookahead)
58 Parser(exprManager,name),
59 d_lookahead(lookahead) {
64 AntlrInput::AntlrInput(ExprManager
* exprManager
, const std::string
& input
, const std::string
& name
, unsigned int lookahead
) :
65 Input(exprManager
,name
),
66 d_lookahead(lookahead
),
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
+ "'");
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
+ "'");
81 AntlrInput::~AntlrInput() {
82 d_tokenStream
->free(d_tokenStream
);
83 d_input
->close(d_input
);
86 pANTLR3_INPUT_STREAM
AntlrInput::getInputStream() {
90 pANTLR3_COMMON_TOKEN_STREAM
AntlrInput::getTokenStream() {
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
);
100 // Call the error display routine
101 parserState
->parseError("Error finding next token.");
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
) << ": "
111 throw ParserException(message
, getParserState()->getFilename(),
112 d_lexer
->getLine(d_lexer
),
113 d_lexer
->getCharPositionInLine(d_lexer
));
117 void AntlrInput::setLexer(pANTLR3_LEXER pLexer
) {
120 pANTLR3_TOKEN_FACTORY pTokenFactory
= d_lexer
->rec
->state
->tokFactory
;
121 if( pTokenFactory
!= NULL
) {
122 pTokenFactory
->close(pTokenFactory
);
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.");
130 d_lexer
->rec
->state
->tokFactory
= pTokenFactory
;
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.");
137 d_tokenStream
= buffer
->commonTstream
;
139 // ANTLR isn't using super, AFAICT.
140 d_lexer
->super
= getParserState();
141 // Override default lexer error reporting
142 d_lexer
->rec
->reportError
= &lexerError
;
145 void AntlrInput::setParser(pANTLR3_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
;
162 }/* CVC4::parser namespace */
163 }/* CVC4 namespace */