Skip to content
Snippets Groups Projects
Unverified Commit b4c04dac authored by dutor's avatar dutor Committed by GitHub
Browse files

Support double format starts or ends with dot (#383)

parent 9c83fc63
No related branches found
No related tags found
No related merge requests found
......@@ -88,6 +88,79 @@ protected:
return sbuf_.get();
}
using TokenType = nebula::GraphParser::token;
auto parseDecimal() const {
try {
folly::StringPiece text(yytext, yyleng);
uint64_t val = folly::to<uint64_t>(text);
if (val > MAX_ABS_INTEGER) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
if (val == MAX_ABS_INTEGER && !hasUnaryMinus()) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
yylval->intval = val;
} catch (...) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
return TokenType::INTEGER;
}
auto parseDouble() const {
try {
folly::StringPiece text(yytext, yyleng);
yylval->doubleval = folly::to<double>(text);
} catch (...) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
return TokenType::DOUBLE;
}
auto parseHex() const {
if (yyleng > 18) {
auto i = 2;
while (i < yyleng && yytext[i] == '0') {
i++;
}
if (yyleng - i > 16) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
}
uint64_t val = 0;
sscanf(yytext, "%lx", &val);
if (val > MAX_ABS_INTEGER) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
if (val == MAX_ABS_INTEGER && !hasUnaryMinus()) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
yylval->intval = static_cast<int64_t>(val);
return TokenType::INTEGER;
}
auto parseOct() const {
if (yyleng > 22) {
auto i = 1;
while (i < yyleng && yytext[i] == '0') {
i++;
}
if (yyleng - i > 22 ||
(yyleng - i == 22 && yytext[i] != '1')) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
}
uint64_t val = 0;
sscanf(yytext, "%lo", &val);
if (val > MAX_ABS_INTEGER) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
if (val == MAX_ABS_INTEGER && !hasUnaryMinus()) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
yylval->intval = static_cast<int64_t>(val);
return TokenType::INTEGER;
}
private:
friend class Scanner_Basic_Test;
int yylex() override;
......
......@@ -158,7 +158,7 @@ static constexpr size_t MAX_ABS_INTEGER = 9223372036854775808ULL;
/* symbols */
%token L_PAREN R_PAREN L_BRACKET R_BRACKET L_BRACE R_BRACE COMMA
%token PIPE ASSIGN
%token DOT COLON SEMICOLON L_ARROW R_ARROW AT
%token DOT DOT_DOT COLON SEMICOLON L_ARROW R_ARROW AT
%token ID_PROP TYPE_PROP SRC_ID_PROP DST_ID_PROP RANK_PROP INPUT_REF DST_REF SRC_REF
/* token type specification */
......@@ -1145,14 +1145,14 @@ match_step_range
| STAR legal_integer {
$$ = new MatchStepRange($2, $2);
}
| STAR DOT DOT legal_integer {
$$ = new MatchStepRange(1, $4);
| STAR DOT_DOT legal_integer {
$$ = new MatchStepRange(1, $3);
}
| STAR legal_integer DOT DOT {
| STAR legal_integer DOT_DOT {
$$ = new MatchStepRange($2);
}
| STAR legal_integer DOT DOT legal_integer {
$$ = new MatchStepRange($2, $5);
| STAR legal_integer DOT_DOT legal_integer {
$$ = new MatchStepRange($2, $4);
}
;
......
......@@ -13,8 +13,6 @@
yylloc->step(); \
yylloc->columns(yyleng);
using TokenType = nebula::GraphParser::token;
static constexpr size_t MAX_STRING = 4096;
%}
......@@ -364,6 +362,7 @@ FORMAT ([Ff][Oo][Rr][Mm][Aa][Tt])
{FALSE} { yylval->boolval = false; return TokenType::BOOL; }
"." { return TokenType::DOT; }
".." { return TokenType::DOT_DOT; }
"," { return TokenType::COMMA; }
":" { return TokenType::COLON; }
";" { return TokenType::SEMICOLON; }
......@@ -433,75 +432,29 @@ FORMAT ([Ff][Oo][Rr][Mm][Aa][Tt])
return TokenType::IPV4;
}
0[Xx]{HEX}+ {
if (yyleng > 18) {
auto i = 2;
while (i < yyleng && yytext[i] == '0') {
i++;
}
if (yyleng - i > 16) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
}
uint64_t val = 0;
sscanf(yytext, "%lx", &val);
if (val > MAX_ABS_INTEGER) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
if (val == MAX_ABS_INTEGER && !hasUnaryMinus()) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
yylval->intval = static_cast<int64_t>(val);
return TokenType::INTEGER;
return parseHex();
}
0{OCT}+ {
if (yyleng > 22) {
auto i = 1;
while (i < yyleng && yytext[i] == '0') {
i++;
}
if (yyleng - i > 22 ||
(yyleng - i == 22 && yytext[i] != '1')) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
}
uint64_t val = 0;
sscanf(yytext, "%lo", &val);
if (val > MAX_ABS_INTEGER) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
if (val == MAX_ABS_INTEGER && !hasUnaryMinus()) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
yylval->intval = static_cast<int64_t>(val);
return TokenType::INTEGER;
return parseOct();
}
{DEC}+\.\. {
yyless(yyleng - 2);
return parseDecimal();
}
{DEC}+ {
try {
folly::StringPiece text(yytext, yyleng);
uint64_t val = folly::to<uint64_t>(text);
if (val > MAX_ABS_INTEGER) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
if (val == MAX_ABS_INTEGER && !hasUnaryMinus()) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
yylval->intval = val;
} catch (...) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
return TokenType::INTEGER;
return parseDecimal();
}
{DEC}+\.{DEC}+ {
try {
folly::StringPiece text(yytext, yyleng);
yylval->doubleval = folly::to<double>(text);
} catch (...) {
throw GraphParser::syntax_error(*yylloc, "Out of range:");
}
return TokenType::DOUBLE;
{DEC}*\.{DEC}+ |
{DEC}+\.{DEC}* {
return parseDouble();
}
\${LABEL} { yylval->strval = new std::string(yytext + 1, yyleng - 1); return TokenType::VARIABLE; }
\${LABEL} {
yylval->strval = new std::string(yytext + 1, yyleng - 1);
return TokenType::VARIABLE;
}
\" { BEGIN(DQ_STR); sbufPos_ = 0; }
......
......@@ -134,6 +134,7 @@ TEST(Scanner, Basic) {
std::vector<Validator> validators = {
CHECK_SEMANTIC_TYPE(".", TokenType::DOT),
CHECK_SEMANTIC_TYPE("..", TokenType::DOT_DOT),
CHECK_SEMANTIC_TYPE(",", TokenType::COMMA),
CHECK_SEMANTIC_TYPE(":", TokenType::COLON),
CHECK_SEMANTIC_TYPE(";", TokenType::SEMICOLON),
......@@ -468,6 +469,8 @@ TEST(Scanner, Basic) {
CHECK_SEMANTIC_VALUE("0x123", TokenType::INTEGER, 0x123),
CHECK_SEMANTIC_VALUE("0xdeadbeef", TokenType::INTEGER, 0xdeadbeef),
CHECK_SEMANTIC_VALUE("0123", TokenType::INTEGER, 0123),
CHECK_SEMANTIC_VALUE("123.", TokenType::DOUBLE, 123.),
CHECK_SEMANTIC_VALUE(".123", TokenType::DOUBLE, 0.123),
CHECK_SEMANTIC_VALUE("123.456", TokenType::DOUBLE, 123.456),
CHECK_SEMANTIC_VALUE("0x7FFFFFFFFFFFFFFF", TokenType::INTEGER, 0x7FFFFFFFFFFFFFFFL),
......
......@@ -135,6 +135,10 @@ TEST_F(YieldValidatorTest, TypeCastTest) {
std::string query = "YIELD (INT)1.23";
EXPECT_TRUE(checkResult(query, expected_));
}
{
std::string query = "YIELD (INT).123";
EXPECT_TRUE(checkResult(query, expected_));
}
{
std::string query = "YIELD (INT)123";
EXPECT_TRUE(checkResult(query, expected_));
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment