Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright Contributors to the OpenVDB Project | ||
2 | // SPDX-License-Identifier: MPL-2.0 | ||
3 | |||
4 | #include "Parse.h" | ||
5 | #include "../Exceptions.h" | ||
6 | |||
7 | // if OPENVDB_AX_REGENERATE_GRAMMAR is defined, we've re-generated the | ||
8 | // grammar - include path should be set up to pull in from the temp dir | ||
9 | // @note We need to include this to get access to axlloc. Should look to | ||
10 | // re-work this so we don't have to (would require a reentrant parser) | ||
11 | #ifdef OPENVDB_AX_REGENERATE_GRAMMAR | ||
12 | #include "axparser.h" | ||
13 | #else | ||
14 | #include "../grammar/generated/axparser.h" | ||
15 | #endif | ||
16 | |||
17 | #include <mutex> | ||
18 | #include <string> | ||
19 | #include <memory> | ||
20 | |||
21 | namespace { | ||
22 | // Declare this at file scope to ensure thread-safe initialization. | ||
23 | std::mutex sInitMutex; | ||
24 | } | ||
25 | |||
26 | openvdb::ax::Logger* axlog = nullptr; | ||
27 | using YY_BUFFER_STATE = struct yy_buffer_state*; | ||
28 | extern int axparse(openvdb::ax::ast::Tree**); | ||
29 | extern YY_BUFFER_STATE ax_scan_string(const char * str); | ||
30 | extern void ax_delete_buffer(YY_BUFFER_STATE buffer); | ||
31 | 505 | extern void axerror (openvdb::ax::ast::Tree**, char const *s) { | |
32 | //@todo: add check for memory exhaustion | ||
33 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 505 times.
|
505 | assert(axlog); |
34 |
2/4✓ Branch 1 taken 505 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 505 times.
✗ Branch 5 not taken.
|
505 | axlog->error(/*starts with 'syntax error, '*/s + 14, |
35 | {axlloc.first_line, axlloc.first_column}); | ||
36 | 505 | } | |
37 | |||
38 | openvdb::ax::ast::Tree::ConstPtr | ||
39 | 3380 | openvdb::ax::ast::parse(const char* code, | |
40 | openvdb::ax::Logger& logger) | ||
41 | { | ||
42 | std::lock_guard<std::mutex> lock(sInitMutex); | ||
43 | 3380 | axlog = &logger; // for lexer errs | |
44 |
1/2✓ Branch 1 taken 3380 times.
✗ Branch 2 not taken.
|
3380 | logger.setSourceCode(code); |
45 | |||
46 | const size_t err = logger.errors(); | ||
47 | |||
48 | // reset all locations | ||
49 | 3380 | axlloc.first_line = axlloc.last_line = 1; | |
50 | 3380 | axlloc.first_column = axlloc.last_column = 1; | |
51 | |||
52 |
1/2✓ Branch 1 taken 3380 times.
✗ Branch 2 not taken.
|
3380 | YY_BUFFER_STATE buffer = ax_scan_string(code); |
53 | |||
54 | 3380 | openvdb::ax::ast::Tree* tree(nullptr); | |
55 |
1/2✓ Branch 1 taken 3380 times.
✗ Branch 2 not taken.
|
3380 | axparse(&tree); |
56 | 3380 | axlog = nullptr; | |
57 | |||
58 |
1/2✓ Branch 1 taken 3380 times.
✗ Branch 2 not taken.
|
3380 | openvdb::ax::ast::Tree::ConstPtr ptr(const_cast<const openvdb::ax::ast::Tree*>(tree)); |
59 | |||
60 |
1/2✓ Branch 1 taken 3380 times.
✗ Branch 2 not taken.
|
3380 | ax_delete_buffer(buffer); |
61 | |||
62 |
2/2✓ Branch 0 taken 517 times.
✓ Branch 1 taken 2863 times.
|
3380 | if (logger.errors() > err) ptr.reset(); |
63 | |||
64 |
2/6✓ Branch 1 taken 3380 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3380 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
6760 | logger.setSourceTree(ptr); |
65 | 3380 | return ptr; | |
66 | } | ||
67 | |||
68 | |||
69 | openvdb::ax::ast::Tree::Ptr | ||
70 | 581 | openvdb::ax::ast::parse(const char* code) | |
71 | { | ||
72 | openvdb::ax::Logger logger( | ||
73 | ✗ | [](const std::string& error) { | |
74 | ✗ | OPENVDB_THROW(openvdb::AXSyntaxError, error); | |
75 |
2/6✓ Branch 3 taken 581 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 581 times.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
1743 | }); |
76 | |||
77 |
1/2✓ Branch 1 taken 581 times.
✗ Branch 2 not taken.
|
581 | openvdb::ax::ast::Tree::ConstPtr constTree = openvdb::ax::ast::parse(code, logger); |
78 | |||
79 | 1162 | return std::const_pointer_cast<openvdb::ax::ast::Tree>(constTree); | |
80 | } | ||
81 | |||
82 |