Query parser is somewhat more restrictive now and doesn't read everything as cell expression.

This commit is contained in:
Matthias Koefferlein 2022-02-11 00:30:08 +01:00
parent 5dd50d2f59
commit 75aaf10512
1 changed files with 93 additions and 31 deletions

View File

@ -42,10 +42,69 @@ namespace db
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
// Some utilities // Some utilities
bool check_trailing_reserved_word (const tl::Extractor &ex0) static const char *s_select = "select";
static const char *s_delete = "delete";
static const char *s_or = "or";
static const char *s_of = "of";
static const char *s_on = "on";
static const char *s_do = "do";
static const char *s_from = "from";
static const char *s_layer = "layer";
static const char *s_layers = "layers";
static const char *s_cell = "cell";
static const char *s_cells = "cells";
static const char *s_where = "where";
static const char *s_shapes = "shapes";
static const char *s_polygons = "polygons";
static const char *s_boxes = "boxes";
static const char *s_edges = "edges";
static const char *s_paths = "paths";
static const char *s_texts = "texts";
static const char *s_instances = "instances";
static const char *s_arrays = "arrays";
static const char *s_sorted = "sorted";
static const char *s_unique = "unique";
static const char *s_by = "by";
static const char *s_with = "with";
static const char *s_pass = "pass";
const char *s_reserved_words[] = {
s_select,
s_delete,
s_or,
s_of,
s_on,
s_do,
s_from,
s_layer,
s_layers,
s_cell,
s_cells,
s_where,
s_shapes,
s_polygons,
s_boxes,
s_edges,
s_paths,
s_texts,
s_instances,
s_arrays,
s_sorted,
s_unique,
s_by,
s_with,
s_pass
};
bool check_trailing_reserved_word (const tl::Extractor &ex0)
{ {
tl::Extractor ex = ex0; tl::Extractor ex = ex0;
return (ex.test ("do") || ex.test ("sorted") || ex.test ("pass") || ex.test ("where")); for (size_t i = 0; i < sizeof (s_reserved_words) / sizeof (s_reserved_words[0]); ++i) {
if (ex.test (s_reserved_words[i])) {
return true;
}
}
return false;
} }
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
@ -2370,7 +2429,7 @@ parse_cell_name_filter_element (tl::Extractor &ex, LayoutQuery *q, ChildCellFilt
std::unique_ptr<FilterBracket> b (new FilterBracket (q)); std::unique_ptr<FilterBracket> b (new FilterBracket (q));
do { do {
parse_cell_name_filter_seq (ex, q, b.get (), instance_mode, reading); parse_cell_name_filter_seq (ex, q, b.get (), instance_mode, reading);
} while (ex.test (",") || ex.test ("or")); } while (ex.test (",") || ex.test (s_or));
// TODO: do this in the optimization // TODO: do this in the optimization
if (b->children ().size () == 1 && dynamic_cast<FilterBracket *> (b->children ()[0])) { if (b->children ().size () == 1 && dynamic_cast<FilterBracket *> (b->children ()[0])) {
@ -2507,21 +2566,21 @@ parse_cell_filter (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bo
std::unique_ptr<FilterBracket> b (new FilterBracket (q)); std::unique_ptr<FilterBracket> b (new FilterBracket (q));
if (ex.test ("instances")) { if (ex.test (s_instances)) {
(ex.test ("of") || ex.test ("from")) && (ex.test ("cells") || ex.test ("cell")); (ex.test (s_of) || ex.test (s_from)) && (ex.test (s_cells) || ex.test (s_cell));
// Because an array member cannot be modified we use ArrayInstances in the modification case always // Because an array member cannot be modified we use ArrayInstances in the modification case always
parse_cell_name_filter_seq (ex, q, b.get (), reading ? ExplodedInstances : ArrayInstances, reading); parse_cell_name_filter_seq (ex, q, b.get (), reading ? ExplodedInstances : ArrayInstances, reading);
} else if (ex.test ("arrays")) { } else if (ex.test (s_arrays)) {
(ex.test ("of") || ex.test ("from")) && (ex.test ("cells") || ex.test ("cell")); (ex.test (s_of) || ex.test (s_from)) && (ex.test (s_cells) || ex.test (s_cell));
parse_cell_name_filter_seq (ex, q, b.get (), ArrayInstances, reading); parse_cell_name_filter_seq (ex, q, b.get (), ArrayInstances, reading);
} else { } else {
ex.test ("cells") || ex.test ("cell"); ex.test (s_cells) || ex.test (s_cell);
parse_cell_name_filter_seq (ex, q, b.get (), NoInstances, reading); parse_cell_name_filter_seq (ex, q, b.get (), NoInstances, reading);
} }
FilterBase *fl = 0, *f = 0; FilterBase *fl = 0, *f = 0;
if (with_where_clause && ex.test ("where")) { if (with_where_clause && ex.test (s_where)) {
std::string expr = tl::Eval::parse_expr (ex, true); std::string expr = tl::Eval::parse_expr (ex, true);
@ -2552,22 +2611,22 @@ parse_filter (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool re
{ {
unsigned int sf = (unsigned int) db::ShapeIterator::Nothing; unsigned int sf = (unsigned int) db::ShapeIterator::Nothing;
do { do {
if (ex.test ("shapes")) { if (ex.test (s_shapes)) {
sf |= (unsigned int) db::ShapeIterator::All; sf |= (unsigned int) db::ShapeIterator::All;
} else if (ex.test ("polygons")) { } else if (ex.test (s_polygons)) {
sf |= (unsigned int) db::ShapeIterator::Polygons; sf |= (unsigned int) db::ShapeIterator::Polygons;
} else if (ex.test ("boxes")) { } else if (ex.test (s_boxes)) {
sf |= (unsigned int) db::ShapeIterator::Boxes; sf |= (unsigned int) db::ShapeIterator::Boxes;
} else if (ex.test ("edges")) { } else if (ex.test (s_edges)) {
sf |= (unsigned int) db::ShapeIterator::Edges; sf |= (unsigned int) db::ShapeIterator::Edges;
} else if (ex.test ("paths")) { } else if (ex.test (s_paths)) {
sf |= (unsigned int) db::ShapeIterator::Paths; sf |= (unsigned int) db::ShapeIterator::Paths;
} else if (ex.test ("texts")) { } else if (ex.test (s_texts)) {
sf |= (unsigned int) db::ShapeIterator::Texts; sf |= (unsigned int) db::ShapeIterator::Texts;
} else { } else {
break; break;
} }
} while (ex.test (",") || ex.test ("or")); } while (ex.test (",") || ex.test (s_or));
db::ShapeIterator::flags_type shapes = (db::ShapeIterator::flags_type) sf; db::ShapeIterator::flags_type shapes = (db::ShapeIterator::flags_type) sf;
@ -2575,12 +2634,12 @@ parse_filter (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool re
db::LayerMap lm; db::LayerMap lm;
if (ex.test ("on")) { if (ex.test (s_on)) {
ex.test ("layer") || ex.test ("layers"); ex.test (s_layer) || ex.test (s_layers);
lm.map_expr (ex, 0); lm.map_expr (ex, 0);
} }
ex.test ("of") || ex.test ("from"); ex.test (s_of) || ex.test (s_from);
std::unique_ptr<FilterBracket> b (new FilterBracket (q)); std::unique_ptr<FilterBracket> b (new FilterBracket (q));
parse_cell_filter (ex, q, b.get (), false, reading); parse_cell_filter (ex, q, b.get (), false, reading);
@ -2596,7 +2655,7 @@ parse_filter (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool re
bracket->add_child (f); bracket->add_child (f);
fl->connect (f); fl->connect (f);
if (ex.test ("where")) { if (ex.test (s_where)) {
std::string expr = tl::Eval::parse_expr (ex, true); std::string expr = tl::Eval::parse_expr (ex, true);
@ -2617,7 +2676,7 @@ parse_filter (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool re
void void
parse_statement (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool reading) parse_statement (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool reading)
{ {
if (ex.test ("select")) { if (ex.test (s_select)) {
std::vector<std::string> expressions; std::vector<std::string> expressions;
@ -2625,7 +2684,7 @@ parse_statement (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool
expressions.push_back (tl::Eval::parse_expr (ex, true)); expressions.push_back (tl::Eval::parse_expr (ex, true));
} while (ex.test (",")); } while (ex.test (","));
ex.expect ("from"); ex.expect (s_from);
std::unique_ptr<FilterBracket> b (new FilterBracket (q)); std::unique_ptr<FilterBracket> b (new FilterBracket (q));
parse_filter (ex, q, b.get (), true); parse_filter (ex, q, b.get (), true);
@ -2633,10 +2692,10 @@ parse_statement (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool
bool unique = false; bool unique = false;
std::string sort_expression; std::string sort_expression;
if (ex.test ("sorted")) { if (ex.test (s_sorted)) {
ex.test ("by"); ex.test (s_by);
sort_expression = tl::Eval::parse_expr (ex, true); sort_expression = tl::Eval::parse_expr (ex, true);
unique = ex.test ("unique"); unique = ex.test (s_unique);
} }
FilterBase *f = b.release (); FilterBase *f = b.release ();
@ -2649,16 +2708,16 @@ parse_statement (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool
bracket->connect_exit (ff); bracket->connect_exit (ff);
} else if (! reading && ex.test ("with")) { } else if (! reading && ex.test (s_with)) {
std::unique_ptr<FilterBracket> b (new FilterBracket (q)); std::unique_ptr<FilterBracket> b (new FilterBracket (q));
parse_filter (ex, q, b.get (), false); parse_filter (ex, q, b.get (), false);
ex.expect ("do"); ex.expect (s_do);
std::string expression = tl::Eval::parse_expr (ex, true); std::string expression = tl::Eval::parse_expr (ex, true);
bool transparent = ex.test ("pass"); bool transparent = ex.test (s_pass);
FilterBase *f = b.release (); FilterBase *f = b.release ();
bracket->add_child (f); bracket->add_child (f);
@ -2670,12 +2729,12 @@ parse_statement (tl::Extractor &ex, LayoutQuery *q, FilterBracket *bracket, bool
bracket->connect_exit (ff); bracket->connect_exit (ff);
} else if (! reading && ex.test ("delete")) { } else if (! reading && ex.test (s_delete)) {
std::unique_ptr<FilterBracket> b (new FilterBracket (q)); std::unique_ptr<FilterBracket> b (new FilterBracket (q));
parse_filter (ex, q, b.get (), false); parse_filter (ex, q, b.get (), false);
bool transparent = ex.test ("pass"); bool transparent = ex.test (s_pass);
FilterBase *f = b.release (); FilterBase *f = b.release ();
bracket->add_child (f); bracket->add_child (f);
@ -2699,7 +2758,10 @@ LayoutQuery::LayoutQuery (const std::string &query)
tl::Extractor ex (query.c_str ()); tl::Extractor ex (query.c_str ());
parse_statement (ex, this, r.get (), false); parse_statement (ex, this, r.get (), false);
ex.expect_end ();
if (! ex.at_end ()) {
ex.error (tl::to_string (tr ("Unexpected text")));
}
r->optimize (); r->optimize ();
mp_root = r.release (); mp_root = r.release ();