diff --git a/.devcontainer/fedora/devcontainer.json b/.devcontainer/fedora/devcontainer.json index 77a7caf38..3a9f3f737 100644 --- a/.devcontainer/fedora/devcontainer.json +++ b/.devcontainer/fedora/devcontainer.json @@ -1,5 +1,5 @@ { - "name": "helio", + "name": "fedora30", "image": "ghcr.io/romange/fedora:30", "customizations": { "vscode": { diff --git a/.devcontainer/ubuntu20/cmake-tools-kits.json b/.devcontainer/ubuntu20/cmake-tools-kits.json new file mode 100644 index 000000000..de7796c64 --- /dev/null +++ b/.devcontainer/ubuntu20/cmake-tools-kits.json @@ -0,0 +1,10 @@ +[ + { + "name": "GCC x86_64-linux-gnu", + "compilers": { + "C": "gcc", + "CXX": "g++" + }, + "isTrusted": true + } +] diff --git a/.devcontainer/ubuntu20/devcontainer.json b/.devcontainer/ubuntu20/devcontainer.json new file mode 100644 index 000000000..30391947e --- /dev/null +++ b/.devcontainer/ubuntu20/devcontainer.json @@ -0,0 +1,21 @@ +{ + "name": "ubuntu20", + "image": "ghcr.io/romange/ubuntu-dev:20", + "customizations": { + "vscode": { + "extensions": [ + "ms-vscode.cpptools", + "ms-vscode.cmake-tools", + "ms-vscode.cpptools-themes", + "twxs.cmake" + ], + "settings": { + "cmake.buildDirectory": "/build" + } + } + }, + "mounts": [ + "source=ubuntu20-vol,target=/build,type=volume" + ], + "postCreateCommand": ".devcontainer/ubuntu20/post-create.sh ${containerWorkspaceFolder}" +} diff --git a/.devcontainer/ubuntu20/post-create.sh b/.devcontainer/ubuntu20/post-create.sh new file mode 100755 index 000000000..84f51ec35 --- /dev/null +++ b/.devcontainer/ubuntu20/post-create.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +containerWorkspaceFolder=$1 +git config --global --add safe.directory ${containerWorkspaceFolder}/helio +mkdir -p /root/.local/share/CMakeTools +cp ${containerWorkspaceFolder}/.devcontainer/ubuntu20/cmake-tools-kits.json /root/.local/share/CMakeTools/ diff --git a/src/core/json/jsonpath_grammar.y b/src/core/json/jsonpath_grammar.y index c2785204b..6f23a826b 100644 --- a/src/core/json/jsonpath_grammar.y +++ b/src/core/json/jsonpath_grammar.y @@ -45,12 +45,15 @@ using namespace std; %token LBRACKET "[" + RBRACKET "]" ROOT "$" DOT "." + WILDCARD "*" // Needed 0 at the end to satisfy bison 3.5.1 %token YYEOF 0 -%token UNQ_STR "unq_str" +%token UNQ_STR "unquoted string" +%token UINT "integer" %% // Based on the following specification: @@ -60,14 +63,21 @@ jsonpath: ROOT | ROOT relative_location relative_location: DOT relative_path + | LBRACKET bracket_expr RBRACKET -relative_path: identifier - | identifier relative_location +relative_path: identifier opt_relative_location + | WILDCARD opt_relative_location -identifier: unquoted_string +opt_relative_location: + | relative_location + +identifier: UNQ_STR // | single_quoted_string | double_quoted_string -unquoted_string : UNQ_STR +bracket_expr: WILDCARD + | index_expr + +index_expr: UINT %% diff --git a/src/core/json/jsonpath_lexer.lex b/src/core/json/jsonpath_lexer.lex index 458aa870e..e051ddf71 100644 --- a/src/core/json/jsonpath_lexer.lex +++ b/src/core/json/jsonpath_lexer.lex @@ -5,7 +5,8 @@ %{ - // SECOND SECTION + #include + #include "base/logging.h" %} %o bison-cc-namespace="dfly.json" bison-cc-parser="Parser" @@ -41,6 +42,14 @@ "$" return Parser::make_ROOT(loc()); "." return Parser::make_DOT(loc()); +"[" return Parser::make_LBRACKET(loc()); +"]" return Parser::make_RBRACKET(loc()); +"*" return Parser::make_WILDCARD(loc()); +[0-9]{1,9} { + unsigned val; + CHECK(absl::SimpleAtoi(str(), &val)); + return Parser::make_UINT(val, loc()); + } \w[\w_\-]* return Parser::make_UNQ_STR(str(), loc()); <> printf("EOF%s\n", matcher().text()); %% diff --git a/src/core/json/jsonpath_test.cc b/src/core/json/jsonpath_test.cc index a1ee50592..8ab9f6ef6 100644 --- a/src/core/json/jsonpath_test.cc +++ b/src/core/json/jsonpath_test.cc @@ -31,21 +31,28 @@ class JsonPathTest : public ::testing::Test { #define NEXT_TOK(tok_enum) \ { \ auto tok = Lex(); \ - ASSERT_EQ(tok.type_get(), Parser::token::TOK_##tok_enum); \ + ASSERT_EQ(Parser::token::TOK_##tok_enum, tok.type_get()); \ } #define NEXT_EQ(tok_enum, type, val) \ { \ auto tok = Lex(); \ - ASSERT_EQ(tok.type_get(), Parser::token::TOK_##tok_enum); \ + ASSERT_EQ(Parser::token::TOK_##tok_enum, tok.type_get()); \ EXPECT_EQ(val, tok.value.as()); \ } TEST_F(JsonPathTest, Scanner) { - SetInput("$.мага-зин2.book[0].title"); + SetInput("$.мага-зин2.book[0].*"); NEXT_TOK(ROOT); NEXT_TOK(DOT); NEXT_EQ(UNQ_STR, string, "мага-зин2"); + NEXT_TOK(DOT); + NEXT_EQ(UNQ_STR, string, "book"); + NEXT_TOK(LBRACKET); + NEXT_EQ(UINT, unsigned, 0); + NEXT_TOK(RBRACKET); + NEXT_TOK(DOT); + NEXT_TOK(WILDCARD); } } // namespace dfly::json