1
0
Fork 0
arangodb/JsonParserX/JsonScannerX.ll

308 lines
9.4 KiB
LLVM

%{ /* -*- C++ -*- */
////////////////////////////////////////////////////////////////////////////////
/// @brief flex scanner
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2011 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Oreste Costa-Panaia
/// @author Copyright 2010-2011, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "Basics/StringUtils.h"
#include <cstdlib>
#include <errno.h>
#include <limits.h>
#include <string>
#include "JsonParserX/JsonParserXDriver.h"
#include "JsonParserX/JsonParserX.h"
using namespace triagens::basics;
using namespace triagens::rest;
#if defined(_MSC_VER)
#pragma warning( disable : 4018 )
#endif
/* Work around an incompatibility in flex (at least versions
2.5.31 through 2.5.33): it generates code that does
not conform to C89. See Debian bug 333231
<http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>. */
/* By default yylex returns int, we use token_type.
Unfortunately yyterminate by default returns 0, which is
not of token_type. */
#define yyterminate() return token::END
#define YYSTYPE NAME_SPACE::JsonParserX::semantic_type
#define YYLTYPE NAME_SPACE::location
/* NOT USABLE HERE too MANY THREADS std::string buffer; */
%}
%option reentrant
%option bison-bridge
%option bison-locations
%option noyywrap nounput batch debug
%x STRINGS
%x UNQUOTED_STRINGS
blank [ \t]
ZERO [0]
DIGIT [0-9]
DIGIT1 [1-9]
HEXDIGIT [0123456789abcdefABCDEF]{1}
MINUS [-]
PLUS [+]
%{
#define YY_EXTRA_TYPE triagens::rest::JsonParserXDriver*
#define YY_USER_ACTION yylloc->columns(yyleng);
%}
%%
%{
%}
{blank}+ {
yylloc->step();
}
[\n]+ {
yylloc->lines(yyleng);
yylloc->step();
}
%{
typedef NAME_SPACE::JsonParserX::token token;
%}
/****************************** normal strings *******************************/
\" {
BEGIN STRINGS;
yyextra->buffer = "";
}
<STRINGS>\\\" { yyextra->buffer.push_back('\"'); }
<STRINGS>\\\\ { yyextra->buffer.push_back('\\'); }
<STRINGS>\\\/ { yyextra->buffer.push_back('/'); }
<STRINGS>\\b { yyextra->buffer.push_back('\b'); }
<STRINGS>\\f { yyextra->buffer.push_back('\f'); }
<STRINGS>\\n { yyextra->buffer.push_back('\n'); }
<STRINGS>\\r { yyextra->buffer.push_back('\r'); }
<STRINGS>\\t { yyextra->buffer.push_back('\t'); }
<STRINGS>\\(?i:u){HEXDIGIT}{HEXDIGIT}{HEXDIGIT}{HEXDIGIT} {
StringUtils::unicodeToUTF8(&yytext[2],4, yyextra->buffer);
//should be terminate if incorrect unicode?
//yyterminate(); -- call this to prematurely terminate the scanning
}
<STRINGS>\\(?i:u)([Dd][89ABab]{HEXDIGIT}{HEXDIGIT})\\(?i:u)([Dd][CDEFcdef]{HEXDIGIT}{HEXDIGIT}) {
StringUtils::convertUTF16ToUTF8(&yytext[2], &yytext[8], yyextra->buffer);
}
<STRINGS>\" {
BEGIN 0;
yylval->str = new std::string(yyextra->buffer);
return token::STRING_CONSTANT;
}
<STRINGS>[\x20\x21\x23-\x2e\x3a-\x40\x5b\x5d`{}|~A-Za-z0-9_]* {
yyextra->buffer.append(yytext,yyleng);
}
<STRINGS>. {
yyextra->buffer.push_back(yytext[0]);
}
/****************************** identifiers and Keywords *********************/
(?i:false) { return token::FALSE_CONSTANT; }
(?i:null) { return token::NULL_CONSTANT; }
(?i:true) { return token::TRUE_CONSTANT; }
/*****************************************************************************/
/****************************** INTEGERS *************************************/
/*****************************************************************************/
/*****************************************************************************/
/* Integer with 'L' or 'l' are 64 bit */
/*****************************************************************************/
/* -- long zero -- */
({MINUS}|{PLUS})?{ZERO}[lL] {
yylval->int64_type = 0;
return token::SIGNED_LONG_INTEGER_CONSTANT;
}
/* -- unsigned long zero -- */
[uU]{ZERO}[lL] {
yylval->uint64_type = 0;
return token::UNSIGNED_LONG_INTEGER_CONSTANT;
}
/* -- long integer -- */
({MINUS}|{PLUS})?{DIGIT1}{DIGIT}*[lL] {
yylval->int64_type = StringUtils::int64(yytext, yyleng - 1);
return token::SIGNED_LONG_INTEGER_CONSTANT;
}
/* -- unsigned long integer -- */
[uU]{DIGIT1}{DIGIT}*[lL] {
yylval->uint64_type = StringUtils::uint64(yytext + 1, yyleng - 2);
return token::UNSIGNED_LONG_INTEGER_CONSTANT;
}
/*****************************************************************************/
/* Integer without 'L' or 'l' are also 64 bit */
/*****************************************************************************/
/* -- zero -- */
({MINUS}|{PLUS})?{ZERO} {
yylval->int64_type = 0;
return token::SIGNED_LONG_INTEGER_CONSTANT;
}
/* -- unsigned zero -- */
[uU]{ZERO} {
yylval->uint64_type = 0;
return token::UNSIGNED_LONG_INTEGER_CONSTANT;
}
/* -- integer -- */
({MINUS}|{PLUS})?{DIGIT1}{DIGIT}* {
yylval->int64_type = StringUtils::int64(yytext, yyleng);
return token::SIGNED_LONG_INTEGER_CONSTANT;
}
/* -- unsigned integer -- */
[uU]{DIGIT1}{DIGIT}* {
yylval->uint64_type = StringUtils::uint64(yytext + 1, yyleng - 1);
return token::UNSIGNED_LONG_INTEGER_CONSTANT;
}
/*******************************************************************************/
/* floats with exponents */
/*******************************************************************************/
/* -- decimal with exponent beginning with zero -- */
({MINUS}|{PLUS})?{ZERO}\.{DIGIT}+[eE]({MINUS}|{PLUS})?{DIGIT}+ {
yylval->double_type = StringUtils::doubleDecimal(yytext, yyleng);
return token::DECIMAL_CONSTANT;
}
/* -- decimal with exponent not starting with ZERO -- */
({MINUS}|{PLUS})?{DIGIT1}{DIGIT}*\.{DIGIT}+[eE]({MINUS}|{PLUS})?{DIGIT}+ {
yylval->double_type = StringUtils::doubleDecimal(yytext, yyleng);
return token::DECIMAL_CONSTANT;
}
/*******************************************************************************/
/* floats without exponents */
/*******************************************************************************/
/* -- decimal without exponent beginning with zero -- */
({MINUS}|{PLUS})?{ZERO}\.{DIGIT}+ {
yylval->double_type = StringUtils::doubleDecimal(yytext, yyleng);
return token::DECIMAL_CONSTANT;
}
/* -- decimal without exponent not starting with ZERO -- */
({MINUS}|{PLUS})?{DIGIT1}{DIGIT}*\.{DIGIT}+ {
yylval->double_type = StringUtils::doubleDecimal(yytext, yyleng);
return token::DECIMAL_CONSTANT;
}
/*******************************************************************************/
/* special characters */
/*******************************************************************************/
"}" { return token::CLOSE_BRACE; }
"]" { return token::CLOSE_BRACKET; }
"{" { return token::OPEN_BRACE; }
"[" { return token::OPEN_BRACKET; }
"," { return token::COMMA; }
":" { return token::COLON; }
/* these special characters are here only to report an error which can easily be detected */
"&&" { return token::AND; }
":=" { return token::ASSIGN; }
")" { return token::CLOSE_PAREN; }
"." { return token::DOT; }
"==" { return token::EQ; }
">=" { return token::GE; }
">" { return token::GT; }
"<=" { return token::LE; }
"<" { return token::LT; }
"-" { return token::MINUS; }
"<>" { return token::NE; }
"!=" { return token::NE; }
"||" { return token::OR; }
"(" { return token::OPEN_PAREN; }
"+" { return token::PLUS; }
";" { return token::SEMICOLON; }
"*" { return token::TIMES; }
"/" { return token::QUOTIENT; }
/*******************************************************************************/
/* unquoted */
/*******************************************************************************/
/* whatever is left, should be an unquoted string appearing somewhere this */
/* will be reported as an error */
. {
return token::UNQUOTED_STRING;
}
%%
void JsonParserXDriver::doParse () {
NAME_SPACE::JsonParserX parser(*this);
parser.set_debug_level(traceParsing);
parser.parse();
}
void JsonParserXDriver::scan_begin () {
yylex_init_extra(this,&scanner);
yyset_debug(traceScanning,scanner);
yy_scan_string(scanString,scanner);
}
void JsonParserXDriver::scan_end () {
yylex_destroy(scanner);
}