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