souffle  2.0.2-371-g6315b36
ParserDriver.cpp
Go to the documentation of this file.
1 /*
2  * Souffle - A Datalog Compiler
3  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved
4  * Licensed under the Universal Permissive License v 1.0 as shown at:
5  * - https://opensource.org/licenses/UPL
6  * - <souffle root>/licenses/SOUFFLE-UPL.txt
7  */
8 
9 /************************************************************************
10  *
11  * @file ParserDriver.cpp
12  *
13  * Defines the parser driver.
14  *
15  ***********************************************************************/
16 
17 #include "parser/ParserDriver.h"
18 #include "Global.h"
19 #include "ast/Clause.h"
20 #include "ast/Component.h"
21 #include "ast/ComponentInit.h"
22 #include "ast/Directive.h"
23 #include "ast/FunctorDeclaration.h"
24 #include "ast/Pragma.h"
25 #include "ast/Program.h"
26 #include "ast/QualifiedName.h"
27 #include "ast/Relation.h"
28 #include "ast/SubsetType.h"
29 #include "ast/TranslationUnit.h"
30 #include "ast/Type.h"
31 #include "ast/utility/Utils.h"
32 #include "reports/ErrorReport.h"
38 #include <memory>
39 #include <utility>
40 #include <vector>
41 
42 using YY_BUFFER_STATE = struct yy_buffer_state*;
43 extern YY_BUFFER_STATE yy_scan_string(const char*, yyscan_t scanner);
44 extern int yylex_destroy(yyscan_t scanner);
45 extern int yylex_init_extra(scanner_data* data, yyscan_t* scanner);
46 extern void yyset_in(FILE* in_str, yyscan_t scanner);
47 
48 namespace souffle {
49 
51  const std::string& filename, FILE* in, ErrorReport& errorReport, DebugReport& debugReport) {
52  translationUnit = mk<ast::TranslationUnit>(mk<ast::Program>(), errorReport, debugReport);
53  yyscan_t scanner;
55  data.yyfilename = filename;
56  yylex_init_extra(&data, &scanner);
57  yyset_in(in, scanner);
58 
59  yy::parser parser(*this, scanner);
60  parser.parse();
61 
62  yylex_destroy(scanner);
63 
64  return std::move(translationUnit);
65 }
66 
68  const std::string& code, ErrorReport& errorReport, DebugReport& debugReport) {
69  translationUnit = mk<ast::TranslationUnit>(mk<ast::Program>(), errorReport, debugReport);
70 
72  data.yyfilename = "<in-memory>";
73  yyscan_t scanner;
74  yylex_init_extra(&data, &scanner);
75  yy_scan_string(code.c_str(), scanner);
76  yy::parser parser(*this, scanner);
77  parser.parse();
78 
79  yylex_destroy(scanner);
80 
81  return std::move(translationUnit);
82 }
83 
85  const std::string& filename, FILE* in, ErrorReport& errorReport, DebugReport& debugReport) {
86  ParserDriver parser;
87  return parser.parse(filename, in, errorReport, debugReport);
88 }
89 
91  const std::string& code, ErrorReport& errorReport, DebugReport& debugReport) {
92  ParserDriver parser;
93  return parser.parse(code, errorReport, debugReport);
94 }
95 
97  ast::Program& program = translationUnit->getProgram();
98  program.addPragma(std::move(p));
99 }
100 
102  const std::string& name = f->getName();
103  ast::Program& program = translationUnit->getProgram();
104  const ast::FunctorDeclaration* existingFunctorDecl = getIf(program.getFunctorDeclarations(),
105  [&](const ast::FunctorDeclaration* current) { return current->getName() == name; });
106  if (existingFunctorDecl != nullptr) {
108  DiagnosticMessage("Redefinition of functor " + toString(name), f->getSrcLoc()),
109  {DiagnosticMessage("Previous definition", existingFunctorDecl->getSrcLoc())});
110  translationUnit->getErrorReport().addDiagnostic(err);
111  } else {
112  program.addFunctorDeclaration(std::move(f));
113  }
114 }
115 
117  const auto& name = r->getQualifiedName();
118  ast::Program& program = translationUnit->getProgram();
119  if (ast::Relation* prev = getRelation(program, name)) {
121  DiagnosticMessage("Redefinition of relation " + toString(name), r->getSrcLoc()),
122  {DiagnosticMessage("Previous definition", prev->getSrcLoc())});
123  translationUnit->getErrorReport().addDiagnostic(err);
124  } else {
125  program.addRelation(std::move(r));
126  }
127 }
128 
130  ast::Program& program = translationUnit->getProgram();
131  if (directive->getType() == ast::DirectiveType::printsize) {
132  for (const auto& cur : program.getDirectives()) {
133  if (cur->getQualifiedName() == directive->getQualifiedName() &&
134  cur->getType() == ast::DirectiveType::printsize) {
136  DiagnosticMessage("Redefinition of printsize directives for relation " +
137  toString(directive->getQualifiedName()),
138  directive->getSrcLoc()),
139  {DiagnosticMessage("Previous definition", cur->getSrcLoc())});
140  translationUnit->getErrorReport().addDiagnostic(err);
141  return;
142  }
143  }
144  } else if (directive->getType() == ast::DirectiveType::limitsize) {
145  for (const auto& cur : program.getDirectives()) {
146  if (cur->getQualifiedName() == directive->getQualifiedName() &&
147  cur->getType() == ast::DirectiveType::limitsize) {
149  DiagnosticMessage("Redefinition of limitsize directives for relation " +
150  toString(directive->getQualifiedName()),
151  directive->getSrcLoc()),
152  {DiagnosticMessage("Previous definition", cur->getSrcLoc())});
153  translationUnit->getErrorReport().addDiagnostic(err);
154  return;
155  }
156  }
157  }
158  program.addDirective(std::move(directive));
159 }
160 
162  ast::Program& program = translationUnit->getProgram();
163  const auto& name = type->getQualifiedName();
164  auto* existingType = getIf(program.getTypes(),
165  [&](const ast::Type* current) { return current->getQualifiedName() == name; });
166  if (existingType != nullptr) {
168  DiagnosticMessage("Redefinition of type " + toString(name), type->getSrcLoc()),
169  {DiagnosticMessage("Previous definition", existingType->getSrcLoc())});
170  translationUnit->getErrorReport().addDiagnostic(err);
171  } else {
172  program.addType(std::move(type));
173  }
174 }
175 
177  ast::Program& program = translationUnit->getProgram();
178  program.addClause(std::move(c));
179 }
181  ast::Program& program = translationUnit->getProgram();
182  program.addComponent(std::move(c));
183 }
185  ast::Program& program = translationUnit->getProgram();
186  program.addInstantiation(std::move(ci));
187 }
188 
190  if (rel.hasQualifier(RelationQualifier::INPUT)) {
191  addDirective(mk<ast::Directive>(ast::DirectiveType::input, rel.getQualifiedName(), rel.getSrcLoc()));
192  }
193 
194  if (rel.hasQualifier(RelationQualifier::OUTPUT)) {
195  addDirective(mk<ast::Directive>(ast::DirectiveType::output, rel.getQualifiedName(), rel.getSrcLoc()));
196  }
197 
198  if (rel.hasQualifier(RelationQualifier::PRINTSIZE)) {
199  addDirective(
200  mk<ast::Directive>(ast::DirectiveType::printsize, rel.getQualifiedName(), rel.getSrcLoc()));
201  }
202 }
203 
204 std::set<RelationTag> ParserDriver::addDeprecatedTag(
205  RelationTag tag, SrcLocation tagLoc, std::set<RelationTag> tags) {
206  if (!Global::config().has("legacy")) {
207  warning(tagLoc, tfm::format("Deprecated %s qualifier was used", tag));
208  }
209  return addTag(tag, std::move(tagLoc), std::move(tags));
210 }
211 
212 std::set<RelationTag> ParserDriver::addReprTag(
213  RelationTag tag, SrcLocation tagLoc, std::set<RelationTag> tags) {
214  return addTag(tag, {RelationTag::BTREE, RelationTag::BRIE, RelationTag::EQREL}, std::move(tagLoc),
215  std::move(tags));
216 }
217 
218 std::set<RelationTag> ParserDriver::addTag(RelationTag tag, SrcLocation tagLoc, std::set<RelationTag> tags) {
219  return addTag(tag, {tag}, std::move(tagLoc), std::move(tags));
220 }
221 
222 std::set<RelationTag> ParserDriver::addTag(RelationTag tag, std::vector<RelationTag> incompatible,
223  SrcLocation tagLoc, std::set<RelationTag> tags) {
224  if (any_of(incompatible, [&](auto&& x) { return contains(tags, x); })) {
225  error(tagLoc, tfm::format("%s qualifier already set", join(incompatible, "/")));
226  }
227 
228  tags.insert(tag);
229  return tags;
230 }
231 
233  ast::QualifiedName name, ast::QualifiedName baseTypeName, SrcLocation loc) {
234  if (!Global::config().has("legacy")) {
235  warning(loc, "Deprecated type declaration used");
236  }
237  return mk<ast::SubsetType>(std::move(name), std::move(baseTypeName), std::move(loc));
238 }
239 
240 void ParserDriver::warning(const SrcLocation& loc, const std::string& msg) {
241  translationUnit->getErrorReport().addWarning(msg, loc);
242 }
243 void ParserDriver::error(const SrcLocation& loc, const std::string& msg) {
244  translationUnit->getErrorReport().addError(msg, loc);
245 }
246 void ParserDriver::error(const std::string& msg) {
247  translationUnit->getErrorReport().addDiagnostic(
249 }
250 
251 } // end of namespace souffle
souffle::ParserDriver::parseTranslationUnit
static Own< ast::TranslationUnit > parseTranslationUnit(const std::string &filename, FILE *in, ErrorReport &errorReport, DebugReport &debugReport)
Definition: ParserDriver.cpp:84
souffle::ParserDriver::addReprTag
std::set< RelationTag > addReprTag(RelationTag tag, SrcLocation tagLoc, std::set< RelationTag > tags)
Definition: ParserDriver.cpp:212
TranslationUnit.h
err
std::string & err
Definition: json11.h:664
souffle::RelationTag::EQREL
@ EQREL
souffle::ParserDriver::addPragma
void addPragma(Own< ast::Pragma > p)
Definition: ParserDriver.cpp:96
souffle::ast::FunctorDeclaration
User-defined functor declaration.
Definition: FunctorDeclaration.h:49
tinyformat::format
void format(std::ostream &out, const char *fmt)
Definition: tinyformat.h:1089
souffle::ast::Program::getFunctorDeclarations
std::vector< FunctorDeclaration * > getFunctorDeclarations() const
Return functor declarations.
Definition: Program.h:70
Directive.h
souffle::ParserDriver::addDirective
void addDirective(Own< ast::Directive > d)
Definition: ParserDriver.cpp:129
souffle::ParserDriver::addFunctorDeclaration
void addFunctorDeclaration(Own< ast::FunctorDeclaration > f)
Definition: ParserDriver.cpp:101
souffle::ParserDriver::addRelation
void addRelation(Own< ast::Relation > r)
Definition: ParserDriver.cpp:116
Component.h
souffle::contains
bool contains(const C &container, const typename C::value_type &element)
A utility to check generically whether a given element is contained in a given container.
Definition: ContainerUtil.h:75
souffle::Own
std::unique_ptr< A > Own
Definition: ContainerUtil.h:42
souffle::ast::Relation
Defines a relation with a name, attributes, qualifiers, and internal representation.
Definition: Relation.h:49
souffle::DiagnosticMessage
Definition: ErrorReport.h:37
souffle::ParserDriver::addDeprecatedTag
std::set< RelationTag > addDeprecatedTag(RelationTag tag, SrcLocation tagLoc, std::set< RelationTag > tags)
Definition: ParserDriver.cpp:204
souffle::ast::analysis::Type
An abstract base class for types to be covered within a type environment.
Definition: TypeSystem.h:51
souffle::ast::Program::addPragma
void addPragma(Own< Pragma > pragma)
Definition: Program.cpp:95
ComponentInit.h
Relation.h
tinyformat.h
souffle::RelationQualifier::PRINTSIZE
@ PRINTSIZE
souffle::ast::Program::addComponent
void addComponent(Own< Component > component)
Add component.
Definition: Program.h:248
souffle::ParserDriver
Definition: ParserDriver.h:57
souffle::ParserDriver::addInstantiation
void addInstantiation(Own< ast::ComponentInit > ci)
Definition: ParserDriver.cpp:184
Utils.h
Global.h
yyset_in
void yyset_in(FILE *in_str, yyscan_t scanner)
souffle::toString
const std::string & toString(const std::string &str)
A generic function converting strings into strings (trivial case).
Definition: StringUtil.h:234
souffle::ast::Program
The program class consists of relations, clauses and types.
Definition: Program.h:52
souffle::ParserDriver::addType
void addType(Own< ast::Type > type)
Definition: ParserDriver.cpp:161
YY_BUFFER_STATE
struct yy_buffer_state * YY_BUFFER_STATE
Definition: ParserDriver.cpp:42
ContainerUtil.h
souffle::ast::getRelation
Relation * getRelation(const Program &program, const QualifiedName &name)
Returns the relation with the given name in the program.
Definition: Utils.cpp:101
souffle::join
detail::joined_sequence< Iter, Printer > join(const Iter &a, const Iter &b, const std::string &sep, const Printer &p)
Creates an object to be forwarded to some output stream for printing sequences of elements interspers...
Definition: StreamUtil.h:175
souffle::DebugReport
Class representing a HTML report, consisting of a list of sections.
Definition: DebugReport.h:87
StringUtil.h
souffle::any_of
bool any_of(const Container &c, UnaryPredicate p)
A generic test checking whether any elements within a container satisfy a certain predicate.
Definition: FunctionalUtil.h:124
souffle::ast::Program::addType
void addType(Own< Type > type)
Add a type declaration.
Definition: Program.cpp:88
souffle::ast::Program::addClause
void addClause(Own< Clause > clause)
Add a clause.
Definition: Program.cpp:62
souffle::ast::DirectiveType::printsize
@ printsize
souffle::RelationTag
RelationTag
Space of user-chosen tags that a relation can have.
Definition: RelationTag.h:31
souffle::Diagnostic
Definition: ErrorReport.h:76
souffle::ParserDriver::addClause
void addClause(Own< ast::Clause > c)
Definition: ParserDriver.cpp:176
souffle::Diagnostic::Type::ERROR
@ ERROR
Type.h
souffle::ParserDriver::translationUnit
Own< ast::TranslationUnit > translationUnit
Definition: ParserDriver.h:61
souffle::ast::DirectiveType::input
@ input
souffle::ast::Program::addRelation
void addRelation(Own< Relation > relation)
Definition: Program.cpp:43
souffle::ParserDriver::mkDeprecatedSubType
Own< ast::SubsetType > mkDeprecatedSubType(ast::QualifiedName name, ast::QualifiedName attr, SrcLocation loc)
Definition: ParserDriver.cpp:232
souffle::ast::Program::getDirectives
std::vector< Directive * > getDirectives() const
Return relation directives.
Definition: Program.h:75
souffle::ast::Program::getTypes
std::vector< Type * > getTypes() const
Return types.
Definition: Program.h:55
souffle::RelationQualifier::INPUT
@ INPUT
Pragma.h
souffle::scanner_data
Definition: ParserDriver.h:50
SubsetType.h
souffle::getIf
C::value_type getIf(const C &container, std::function< bool(const typename C::value_type)> pred)
Returns the first element in a container that satisfies a given predicate, nullptr otherwise.
Definition: ContainerUtil.h:101
souffle::Global::config
static MainConfig & config()
Definition: Global.h:141
souffle::ParserDriver::addTag
std::set< RelationTag > addTag(RelationTag tag, SrcLocation tagLoc, std::set< RelationTag > tags)
Definition: ParserDriver.cpp:218
FunctorDeclaration.h
QualifiedName.h
Program.h
souffle::ParserDriver::parse
Own< ast::TranslationUnit > parse(const std::string &filename, FILE *in, ErrorReport &errorReport, DebugReport &debugReport)
Definition: ParserDriver.cpp:50
souffle::ast::DirectiveType::output
@ output
souffle::SrcLocation
A class describing a range in an input file.
Definition: SrcLocation.h:32
souffle::ParserDriver::addIoFromDeprecatedTag
void addIoFromDeprecatedTag(ast::Relation &r)
Definition: ParserDriver.cpp:189
StreamUtil.h
souffle::ast::DirectiveType::limitsize
@ limitsize
yy_scan_string
YY_BUFFER_STATE yy_scan_string(const char *, yyscan_t scanner)
Clause.h
souffle::ParserDriver::error
void error(const SrcLocation &loc, const std::string &msg)
Definition: ParserDriver.cpp:243
souffle
Definition: AggregateOp.h:25
souffle::ast::Program::addFunctorDeclaration
void addFunctorDeclaration(Own< FunctorDeclaration > functor)
Definition: Program.cpp:100
souffle::ParserDriver::addComponent
void addComponent(Own< ast::Component > c)
Definition: ParserDriver.cpp:180
TCB_SPAN_NAMESPACE_NAME::detail::data
constexpr auto data(C &c) -> decltype(c.data())
Definition: span.h:210
yylex_init_extra
int yylex_init_extra(scanner_data *data, yyscan_t *scanner)
ParserDriver.h
yylex_destroy
int yylex_destroy(yyscan_t scanner)
souffle::ast::Program::addInstantiation
void addInstantiation(Own< ComponentInit > instantiation)
Add component instantiation.
Definition: Program.h:254
FunctionalUtil.h
souffle::ast::Program::addDirective
void addDirective(Own< Directive > directive)
Add relation directive.
Definition: Program.h:80
souffle::ast::QualifiedName
Qualified Name class defines fully/partially qualified names to identify objects in components.
Definition: QualifiedName.h:39
rel
void rel(size_t limit, bool showLimit=true)
Definition: Tui.h:1086
souffle::ErrorReport
Definition: ErrorReport.h:152
ErrorReport.h
souffle::ParserDriver::warning
void warning(const SrcLocation &loc, const std::string &msg)
Definition: ParserDriver.cpp:240
souffle::yyscan_t
void * yyscan_t
Definition: ParserDriver.h:48
souffle::RelationQualifier::OUTPUT
@ OUTPUT
std::type
ElementType type
Definition: span.h:640
souffle::RelationTag::BRIE
@ BRIE
souffle::RelationTag::BTREE
@ BTREE
p
a horizontalBars(j=m=void 0===a.axisX.type?new c.AutoScaleAxis(c.Axis.units.x, b.normalized.series, o, c.extend({}, a.axisX,{highLow:d, referenceValue:0})):a.axisX.type.call(c, c.Axis.units.x, b.normalized.series, o, c.extend({}, a.axisX,{highLow:d, referenceValue:0})), l=n=void 0===a.axisY.type?new c.StepAxis(c.Axis.units.y, b.normalized.series, o,{ticks:k}):a.axisY.type.call(c, c.Axis.units.y, b.normalized.series, o, a.axisY)) var p
Definition: htmlJsChartistMin.h:15