2 #define YYLTYPE cy::location
3 #include "Cycript.tab.hh"
4 typedef cy::parser::token tk;
6 #define YY_EXTRA_TYPE CYDriver *
8 #define T yylval->newline_ = yyextra->state_ == CYNewLine;
9 #define C T yyextra->state_ = CYClear;
10 #define R T yyextra->state_ = CYRestricted;
12 #define E(prefix) L C BEGIN(INITIAL); { \
13 char *value(reinterpret_cast<char *>(apr_palloc(yyextra->pool_, yyleng + sizeof(prefix)))); \
14 memcpy(value, prefix, sizeof(prefix) - 1); \
15 memcpy(value + sizeof(prefix) - 1, yytext, yyleng); \
16 value[yyleng + sizeof(prefix) - 1] = '\0'; \
17 yylval->literal_ = new CYRegEx(value); \
18 return tk::RegularExpressionLiteral; \
22 if (yyextra->state_ != CYNewLine) { \
23 bool restricted(yyextra->state_ == CYRestricted); \
25 yyextra->state_ = CYClear; \
28 yyextra->state_ = CYNewLine; \
33 yylloc->columns(yyleng); \
37 if (c >= '0' && c <= '9')
39 if (c >= 'a' && c <= 'f')
41 if (c >= 'A' && c <= 'F')
46 #define YY_INPUT(data, value, size) { \
47 if (yyextra->file_ != NULL) { \
48 size_t copy(fread(data, 1, size, yyextra->file_)); \
49 value = copy == 0 ? YY_NULL : copy; \
50 } else if (yyextra->size_ == 0) \
53 size_t copy(std::min(size, yyextra->size_)); \
54 memcpy(data, yyextra->data_, copy); \
55 yyextra->data_ += copy; \
56 yyextra->size_ -= copy; \
65 %option bison-locations
72 Exponent [eE][+-]?[0-9]+
73 Escape \\[\\'"bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|\\\n
75 IdentifierStart [a-zA-Z$_]
76 IdentifierPart [a-zA-Z$_0-9]
79 BackslashSequence \\{NonTerminator}
80 RegularExpressionFirstChar [^\n*\\/]|{BackslashSequence}
81 RegularExpressionChar [^\n\\/]|{BackslashSequence}
82 RegularExpressionFlags {IdentifierPart}*
83 RegularExpressionChars {RegularExpressionChar}*
84 RegularExpressionBody_ {RegularExpressionChars}
85 RegularExpressionBody {RegularExpressionFirstChar}{RegularExpressionBody_}
87 RegularExpressionEnd_ \/{RegularExpressionFlags}
88 RegularExpressionRest_ {RegularExpressionBody_}{RegularExpressionEnd_}
89 RegularExpressionStart_ {RegularExpressionBody}{RegularExpressionEnd_}
96 <res>{RegularExpressionStart_} E("/")
97 <rer>{RegularExpressionRest_} E("/=")
100 \/\*(\n|[^\*]|\*[^/])\*\/ if (memchr(yytext, '\n', yyleng) != NULL) N // XXX: supposedly I will be screwed on very very long multi-line comments and need to replace this with a manual lexer. http://websrv.cs.fsu.edu/~engelen/courses/COP5621/Pr2.pdf ; XXX: this rule doesn't work anyway, fucking A :(
102 "&" L C return tk::Ampersand;
103 "&&" L C return tk::AmpersandAmpersand;
104 "&=" L C return tk::AmpersandEqual;
105 "^" L C return tk::Carrot;
106 "^=" L C return tk::CarrotEqual;
107 "=" L C return tk::Equal;
108 "==" L C return tk::EqualEqual;
109 "===" L C return tk::EqualEqualEqual;
110 "!" L C return tk::Exclamation;
111 "!=" L C return tk::ExclamationEqual;
112 "!==" L C return tk::ExclamationEqualEqual;
113 "-" L C return tk::Hyphen;
114 "-=" L C return tk::HyphenEqual;
115 "--" L C return yylval->newline_ ? tk::HyphenHyphen_ : tk::HyphenHyphen;
116 "->" L C return tk::HyphenRight;
117 "<" L C return tk::Left;
118 "<=" L C return tk::LeftEqual;
119 "<<" L C return tk::LeftLeft;
120 "<<=" L C return tk::LeftLeftEqual;
121 "%" L C return tk::Percent;
122 "%=" L C return tk::PercentEqual;
123 "." L C return tk::Period;
124 "|" L C return tk::Pipe;
125 "|=" L C return tk::PipeEqual;
126 "||" L C return tk::PipePipe;
127 "+" L C return tk::Plus;
128 "+=" L C return tk::PlusEqual;
129 "++" L C return yylval->newline_ ? tk::PlusPlus_ : tk::PlusPlus;
130 ">" L C return tk::Right;
131 ">=" L C return tk::RightEqual;
132 ">>" L C return tk::RightRight;
133 ">>=" L C return tk::RightRightEqual;
134 ">>>" L C return tk::RightRightRight;
135 ">>>=" L C return tk::RightRightRightEqual;
136 "/" L C return tk::Slash;
137 "/=" L C return tk::SlashEqual;
138 "*" L C return tk::Star;
139 "*=" L C return tk::StarEqual;
140 "~" L C return tk::Tilde;
142 ":" L C return tk::Colon;
143 "," L C return tk::Comma;
144 "?" L C return tk::Question;
145 ";" L C return tk::SemiColon;
147 "(" L C return tk::OpenParen;
148 ")" L C return tk::CloseParen;
150 "{" L C return tk::OpenBrace;
151 "}" L C return tk::CloseBrace;
153 "[" L C return tk::OpenBracket;
154 "]" L C return tk::CloseBracket;
156 "@class" L C return tk::AtClass;
157 "@end" L C return tk::AtEnd;
158 "@selector" L C return tk::AtSelector;
160 "false" L C yylval->false_ = new CYFalse(); return tk::False;
161 "null" L C yylval->null_ = new CYNull(); return tk::Null;
162 "true" L C yylval->true_ = new CYTrue(); return tk::True;
164 "break" L R yylval->word_ = new CYWord("break"); return tk::Break;
165 "case" L C yylval->word_ = new CYWord("case"); return tk::Case;
166 "catch" L C yylval->word_ = new CYWord("catch"); return tk::Catch;
167 "continue" L R yylval->word_ = new CYWord("continue"); return tk::Continue;
168 "default" L C yylval->word_ = new CYWord("default"); return tk::Default;
169 "delete" L C yylval->word_ = new CYWord("delete"); return tk::Delete;
170 "do" L C yylval->word_ = new CYWord("do"); return tk::Do;
171 "else" L C yylval->word_ = new CYWord("else"); return tk::Else;
172 "finally" L C yylval->word_ = new CYWord("finally"); return tk::Finally;
173 "for" L C yylval->word_ = new CYWord("for"); return tk::For;
174 "function" L C yylval->word_ = new CYWord("function"); return tk::Function;
175 "if" L C yylval->word_ = new CYWord("if"); return tk::If;
176 "in" L C yylval->word_ = new CYWord("in"); return tk::In;
177 "instanceof" L C yylval->word_ = new CYWord("instanceof"); return tk::InstanceOf;
178 "new" L C yylval->word_ = new CYWord("new"); return tk::New;
179 "return" L R yylval->word_ = new CYWord("return"); return tk::Return;
180 "switch" L C yylval->word_ = new CYWord("switch"); return tk::Switch;
181 "this" L C yylval->this_ = new CYThis(); return tk::This;
182 "throw" L R yylval->word_ = new CYWord("throw"); return tk::Throw;
183 "try" L C yylval->word_ = new CYWord("try"); return tk::Try;
184 "typeof" L C yylval->word_ = new CYWord("typeof"); return tk::TypeOf;
185 "var" L C yylval->word_ = new CYWord("var"); return tk::Var;
186 "void" L C yylval->word_ = new CYWord("void"); return tk::Void;
187 "while" L C yylval->word_ = new CYWord("while"); return tk::While;
188 "with" L C yylval->word_ = new CYWord("with"); return tk::With;
190 "debugger" L C yylval->word_ = new CYWord("debugger"); return tk::Debugger;
192 "const" L C yylval->word_ = new CYWord("const"); return tk::Const;
194 "class" L C yylval->word_ = new CYWord("class"); return tk::Class;
195 "enum" L C yylval->word_ = new CYWord("enum"); return tk::Enum;
196 "export" L C yylval->word_ = new CYWord("export"); return tk::Export;
197 "extends" L C yylval->word_ = new CYWord("extends"); return tk::Extends;
198 "import" L C yylval->word_ = new CYWord("import"); return tk::Import;
199 "super" L C yylval->word_ = new CYWord("super"); return tk::Super;
201 "implements" L C yylval->identifier_ = new CYIdentifier("implements"); return tk::Implements;
202 "interface" L C yylval->identifier_ = new CYIdentifier("interface"); return tk::Interface;
203 "package" L C yylval->identifier_ = new CYIdentifier("package"); return tk::Package;
204 "private" L C yylval->identifier_ = new CYIdentifier("private"); return tk::Private;
205 "protected" L C yylval->identifier_ = new CYIdentifier("protected"); return tk::Protected;
206 "public" L C yylval->identifier_ = new CYIdentifier("public"); return tk::Public;
207 "static" L C yylval->identifier_ = new CYIdentifier("static"); return tk::Static;
209 "abstract" L C yylval->identifier_ = new CYIdentifier("abstract"); return tk::Abstract;
210 "boolean" L C yylval->identifier_ = new CYIdentifier("boolean"); return tk::Boolean;
211 "byte" L C yylval->identifier_ = new CYIdentifier("byte"); return tk::Byte;
212 "char" L C yylval->identifier_ = new CYIdentifier("char"); return tk::Char;
213 "double" L C yylval->identifier_ = new CYIdentifier("double"); return tk::Double;
214 "final" L C yylval->identifier_ = new CYIdentifier("final"); return tk::Final;
215 "float" L C yylval->identifier_ = new CYIdentifier("float"); return tk::Float;
216 "goto" L C yylval->identifier_ = new CYIdentifier("goto"); return tk::Goto;
217 "int" L C yylval->identifier_ = new CYIdentifier("int"); return tk::Int;
218 "long" L C yylval->identifier_ = new CYIdentifier("long"); return tk::Long;
219 "native" L C yylval->identifier_ = new CYIdentifier("native"); return tk::Native;
220 "short" L C yylval->identifier_ = new CYIdentifier("short"); return tk::Short;
221 "synchronized" L C yylval->identifier_ = new CYIdentifier("synchronized"); return tk::Synchronized;
222 "throws" L C yylval->identifier_ = new CYIdentifier("throws"); return tk::Throws;
223 "transient" L C yylval->identifier_ = new CYIdentifier("transient"); return tk::Transient;
224 "volatile" L C yylval->identifier_ = new CYIdentifier("volatile"); return tk::Volatile;
226 "let" L C yylval->identifier_ = new CYIdentifier("let"); return tk::Let;
227 "yield" L C yylval->identifier_ = new CYIdentifier("yield"); return tk::Yield;
229 "each" L C yylval->identifier_ = new CYIdentifier("each"); return tk::Each;
231 {IdentifierStart}{IdentifierPart}* yylval->identifier_ = new CYIdentifier(apr_pstrmemdup(yyextra->pool_, yytext, yyleng)); L C return tk::Identifier_;
233 (\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?){Exponent}? yylval->number_ = new CYNumber(strtod(yytext, NULL)); L C return tk::NumericLiteral;
235 0[xX][0-9a-fA-F]+ L C yylval->number_ = new CYNumber(strtoull(yytext + 2, NULL, 16)); return tk::NumericLiteral;
237 0[bB][0-1]+ L C yylval->number_ = new CYNumber(strtoull(yytext + 2, NULL, 2)); return tk::NumericLiteral;
239 \"([^"\\\n]|{Escape})*\"|'([^'\\\n]|{Escape})*' L C {
240 char *value(reinterpret_cast<char *>(apr_palloc(yyextra->pool_, yyleng)));
243 for (int i(1); i != yyleng - 1; ++i) {
244 char next(yytext[i]);
246 if (yytext[i] == '\\')
247 switch (next = yytext[++i]) {
249 case '\\': next = '\\'; break;
250 case '\'': next = '\''; break;
251 case '"': next = '"'; break;
252 case 'b': next = '\b'; break;
253 case 'f': next = '\f'; break;
254 case 'n': next = '\n'; break;
255 case 'r': next = '\r'; break;
256 case 't': next = '\t'; break;
257 case 'v': next = '\v'; break;
258 case '0': next = '\0'; break;
261 next = H(yytext[i + 1]) << 4 | H(yytext[i + 2]);
270 yylval->string_ = new CYString(value, local - value);
271 return tk::StringLiteral;
274 \n yylloc->end.lines(); yylloc->step(); N
277 <<EOF>> L yyterminate();
280 CYDriver::Error error;
281 error.location_ = *yylloc;
282 error.message_ = "syntax error, unknown token";
283 yyextra->errors_.push_back(error);
289 void CYDriver::ScannerInit() {
290 cylex_init(&scanner_);
291 cyset_extra(this, scanner_);
294 void CYDriver::ScannerDestroy() {
295 cylex_destroy(scanner_);
298 void CYDriver::SetCondition(Condition condition) {
299 struct yyguts_t *yyg(reinterpret_cast<struct yyguts_t *>(scanner_));