1 %{
2 /*****************************************************************************/
3 /*!
4 * \file smtlib2.lex
5 *
6 * Author: Christopher Conway
7 *
8 * Created: 2010
9 *
10 * <hr>
11 *
12 * License to use, copy, modify, sell and/or distribute this software
13 * and its documentation for any purpose is hereby granted without
14 * royalty, subject to the terms and conditions defined in the \ref
15 * LICENSE file provided with this distribution.
16 *
17 * <hr>
18 *
19 */
20 /*****************************************************************************/
21
22 #include <iostream>
23 #include "parser_temp.h"
24 #include "expr_manager.h" /* for the benefit of parsesmtlib_defs.h */
25 #include "parsesmtlib2_defs.h"
26 #include "debug.h"
27
28 namespace CVC3 {
29 extern ParserTemp* parserTemp;
30 }
31
32 extern int smtlib2_inputLine;
33 extern char *smtlib2text;
34
35 extern int smtlib2error (const char *msg);
36
smtlib2input(std::istream & is,char * buf,int size)37 static int smtlib2input(std::istream& is, char* buf, int size) {
38 int res;
39 if(is) {
40 // If interactive, read line by line; otherwise read as much as we
41 // can gobble
42 if(CVC3::parserTemp->interactive) {
43 // Print the current prompt
44 std::cout << CVC3::parserTemp->getPrompt() << std::flush;
45 // Set the prompt to "middle of the command" one
46 CVC3::parserTemp->setPrompt2();
47 // Read the line
48 is.getline(buf, size-1);
49 } else // Set the terminator char to 0
50 is.getline(buf, size-1, 0);
51 // If failbit is set, but eof is not, it means the line simply
52 // didn't fit; so we clear the state and keep on reading.
53 bool partialStr = is.fail() && !is.eof();
54 if(partialStr)
55 is.clear();
56
57 for(res = 0; res<size && buf[res] != 0; res++);
58 if(res == size) smtlib2error("Lexer bug: overfilled the buffer");
59 if(!partialStr) { // Insert \n into the buffer
60 buf[res++] = '\n';
61 buf[res] = '\0';
62 }
63 } else {
64 res = YY_NULL;
65 }
66 return res;
67 }
68
69 // Redefine the input buffer function to read from an istream
70 #define YY_INPUT(buf,result,max_size) \
71 result = smtlib2input(*CVC3::parserTemp->is, buf, max_size);
72
smtlib2_bufSize()73 int smtlib2_bufSize() { return YY_BUF_SIZE; }
smtlib2_buf_state()74 YY_BUFFER_STATE smtlib2_buf_state() { return YY_CURRENT_BUFFER; }
75
76 /* some wrappers for methods that need to refer to a struct.
77 These are used by CVC3::Parser. */
smtlib2_createBuffer(int sz)78 void *smtlib2_createBuffer(int sz) {
79 return (void *)smtlib2_create_buffer(NULL, sz);
80 }
smtlib2_deleteBuffer(void * buf_state)81 void smtlib2_deleteBuffer(void *buf_state) {
82 smtlib2_delete_buffer((struct yy_buffer_state *)buf_state);
83 }
smtlib2_switchToBuffer(void * buf_state)84 void smtlib2_switchToBuffer(void *buf_state) {
85 smtlib2_switch_to_buffer((struct yy_buffer_state *)buf_state);
86 }
smtlib2_bufState()87 void *smtlib2_bufState() {
88 return (void *)smtlib2_buf_state();
89 }
90
smtlib2_setInteractive(bool is_interactive)91 void smtlib2_setInteractive(bool is_interactive) {
92 yy_set_interactive(is_interactive);
93 }
94
95 // File-static (local to this file) variables and functions
96 static std::string _string_lit;
97 static std::string _symbol_text;
98
escapeChar(char c)99 static char escapeChar(char c) {
100 switch(c) {
101 case 'n': return '\n';
102 case 't': return '\t';
103 default: return c;
104 }
105 }
106
107 // for now, we don't have subranges.
108 //
109 // ".." { return DOTDOT_TOK; }
110 /*OPCHAR (['!#?\_$&\|\\@])*/
111
112 %}
113
114 %option noyywrap
115 %option nounput
116 %option noreject
117 %option noyymore
118 %option yylineno
119
120 %x COMMENT
121 %x STRING_LITERAL
122 %x SYMBOL
123 %x USER_VALUE
124 %s PAT_MODE
125
126 LETTER ([a-zA-Z])
127 DIGIT ([0-9])
128 HEX_DIGIT ({DIGIT}|[a-fA-F])
129 BIN_DIGIT ([01])
130 SYMBOL_CHAR ([+\-*/=%?!.$_~&^<>@])
131 SIMPLE_SYMBOL (({LETTER}|{SYMBOL_CHAR})({LETTER}|{DIGIT}|{SYMBOL_CHAR})*)
132
133 %%
134
135 [\n] { CVC3::parserTemp->lineNum++; }
136 [ \t\r\f] { /* skip whitespace */ }
137
138 {DIGIT}+"\."{DIGIT}+ { smtlib2lval.str = new std::string(smtlib2text); return DECIMAL_TOK; }
139 {DIGIT}+ { smtlib2lval.str = new std::string(smtlib2text); return INTEGER_TOK; }
140 "#x"{HEX_DIGIT}+ { /* skip prefix in string value */ smtlib2lval.str = new std::string(smtlib2text+2); return HEX_TOK; }
141 "#b"{BIN_DIGIT}+ { /* skip prefix in string value */ smtlib2lval.str = new std::string(smtlib2text+2); return BINARY_TOK; }
142
143 ";" { BEGIN COMMENT; }
144 <COMMENT>"\n" { BEGIN INITIAL; /* return to normal mode */
145 CVC3::parserTemp->lineNum++; }
146 <COMMENT>. { /* stay in comment mode */ }
147
148 <INITIAL>"\"" { BEGIN STRING_LITERAL;
149 _string_lit.erase(_string_lit.begin(),
150 _string_lit.end()); }
151 <STRING_LITERAL>"\\". { /* escape characters (like \n or \") */
152 _string_lit.insert(_string_lit.end(),
153 escapeChar(smtlib2text[1])); }
154 <STRING_LITERAL>"\"" { BEGIN INITIAL; /* return to normal mode */
155 smtlib2lval.str = new std::string(_string_lit);
156 return STRING_TOK; }
157 <STRING_LITERAL>"\n" { // Include the \n and increment the line number
158 _string_lit.insert(_string_lit.end(),*smtlib2text);
159 CVC3::parserTemp->lineNum++; }
160 <STRING_LITERAL>. { _string_lit.insert(_string_lit.end(),*smtlib2text); }
161
162 <INITIAL>"|" { BEGIN SYMBOL;
163 _symbol_text.erase(_symbol_text.begin(),
164 _symbol_text.end()); }
165 <SYMBOL>"|" { BEGIN INITIAL; /* return to normal mode */
166 smtlib2lval.str = new std::string(_symbol_text);
167 return SYM_TOK; }
168 <SYMBOL>"\n" { // Include the \n and increment the line number
169 _symbol_text.insert(_symbol_text.end(),*smtlib2text);
170 CVC3::parserTemp->lineNum++; }
171 <SYMBOL>. { _symbol_text.insert(_symbol_text.end(),*smtlib2text); }
172
173
174 /* Base SMT-LIB tokens */
175 "assert" { return ASSERT_TOK; }
176 "check-sat" { return CHECKSAT_TOK; }
177 "push" { return PUSH_TOK; }
178 "pop" { return POP_TOK; }
179 "declare-fun" { return DECLARE_FUN_TOK; }
180 "declare-sort" { return DECLARE_SORT_TOK; }
181 "get-proof" { return GET_PROOF_TOK; }
182 "get-assignment" { return GET_ASSIGNMENT_TOK; }
183 "get-value" { return GET_VALUE_TOK; }
184 "get-model" { return GET_MODEL_TOK; }
185 "!" { return EXCLAMATION_TOK; }
186 "exit" { return EXIT_TOK; }
187 "let" { return LET_TOK; }
188 "(" { return LPAREN_TOK; }
189 ")" { return RPAREN_TOK; }
190 "set-logic" { return SET_LOGIC_TOK; }
191 "set-info" { return SET_INFO_TOK; }
192 "_" { return UNDERSCORE_TOK; }
193
194 /* Logic symbols */
195 "exists" { return EXISTS_TOK; }
196 "forall" { return FORALL_TOK; }
197
198 {SIMPLE_SYMBOL} { smtlib2lval.str = new std::string(smtlib2text); return SYM_TOK; }
199
200 ":"{SIMPLE_SYMBOL} { smtlib2lval.str = new std::string(smtlib2text); return KEYWORD_TOK; }
201
202 <<EOF>> { return EOF_TOK; }
203
204 . { smtlib2error("Illegal input character."); }
205 %%
206
207