11#include <QtCore/qbitarray.h>
12#include <QtCore/qtextstream.h>
13#include <QtCore/qfile.h>
14#include <QtCore/qmap.h>
15#include <QtCore/private/qconfig_p.h>
37 generateSeparator(
i,
out);
45QString CppGenerator::copyrightHeader()
const
48 "// " QT_COPYRIGHT
"\n"
49 "// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0\n"
54QString CppGenerator::privateCopyrightHeader()
const
61 "// This file is not part of the Qt API. It exists for the convenience\n"
62 "// of other Qt classes. This header file may change from version to\n"
63 "// version without notice, or even be removed.\n"
87 state_count =
static_cast<int>(aut.
states.size());
88 terminal_count =
static_cast<int>(
grammar.terminals.size());
89 non_terminal_count =
static_cast<int>(
grammar.non_terminals.size());
91#define ACTION(i, j) table [(i) * terminal_count + (j)]
92#define GOTO(i, j) pgoto [(i) * non_terminal_count + (j)]
94 int *
table =
new int [state_count * terminal_count];
95 ::memset (
table, 0, state_count * terminal_count *
sizeof (
int));
97 int *pgoto =
new int [state_count * non_terminal_count];
98 ::memset (pgoto, 0, state_count * non_terminal_count *
sizeof (
int));
101 int shift_reduce_conflict_count = 0;
102 int reduce_reduce_conflict_count = 0;
108 for (Bundle::iterator
a =
state->bundle.begin ();
a !=
state->bundle.end (); ++
a)
110 int symbol = aut.
id (
a.key ());
111 int r = aut.
id (
a.value ());
115 if (
grammar.isNonTerminal (
a.key ()))
117 Q_ASSERT(symbol >= terminal_count && symbol <
static_cast<int>(
grammar.names.size()));
118 GOTO (
q, symbol - terminal_count) =
r;
137 for (
const Name &
s : lookaheads)
147 qout() <<
"*** Warning. Found a reduce/reduce conflict in state " <<
q <<
" on token ``" <<
s <<
"'' between rule "
150 ++reduce_reduce_conflict_count;
165 if (info_r.prec > info_s.prec)
167 else if (info_r.prec == info_s.prec)
169 switch (info_r.assoc) {
185 ++shift_reduce_conflict_count;
188 qout() <<
"*** Warning. Found a shift/reduce conflict in state " <<
q <<
" on token ``" <<
s <<
"'' with rule " <<
r <<
Qt::endl;
195 if (shift_reduce_conflict_count || reduce_reduce_conflict_count)
197 if (shift_reduce_conflict_count !=
grammar.expected_shift_reduce
198 || reduce_reduce_conflict_count !=
grammar.expected_reduce_reduce)
200 qerr() <<
"*** Conflicts: " << shift_reduce_conflict_count <<
" shift/reduce, " << reduce_reduce_conflict_count <<
" reduce/reduce" <<
Qt::endl;
201 if (warnings_are_errors)
203 qerr() <<
"qlalr: error: warning occurred, treating as error due to "
210 qout() <<
Qt::endl <<
"*** Conflicts: " << shift_reduce_conflict_count <<
" shift/reduce, " << reduce_reduce_conflict_count <<
" reduce/reduce" <<
Qt::endl
219 for (
int j = 0;
j < terminal_count; ++
j)
224 used_rules.setBit (-u - 1);
229 for (
int i = 0;
i < used_rules.size(); ++
i, ++
rule)
231 if (! used_rules.testBit (
i))
236 if (warnings_are_errors)
238 qerr() <<
"qlalr: error: warning occurred, treating as error due to "
249 for (
int j = 0;
j < terminal_count; ++
j)
264 defgoto.
resize (non_terminal_count);
265 for (
int j = 0;
j < non_terminal_count; ++
j)
267 count.fill (0, state_count);
269 int &mx = defgoto [
j];
271 for (
int i = 0;
i < state_count; ++
i)
285 for (
int i = 0;
i < state_count; ++
i)
287 for (
int j = 0;
j < non_terminal_count; ++
j)
291 if (
r == defgoto [
j])
296 compressed_action (
table, state_count, terminal_count);
297 compressed_goto (pgoto, state_count, non_terminal_count);
308 if (!
grammar.merged_output.isEmpty())
322 out << copyrightHeader()
323 << privateCopyrightHeader()
327 out <<
"// This file was generated by qlalr - DO NOT EDIT!\n";
356 fprintf (stderr,
"*** cannot create %s: %s\n",
367 out << copyrightHeader()
368 << privateCopyrightHeader()
372 out <<
"// This file was generated by qlalr - DO NOT EDIT!\n";
393 fprintf (stderr,
"*** cannot create %s: %s\n",
401 out << copyrightHeader();
403 out <<
"// This file was generated by qlalr - DO NOT EDIT!\n";
414 if (!
grammar.decl_file_name.isEmpty ())
419 fprintf (stderr,
"*** cannot create %s: %s\n",
427 if (!
grammar.impl_file_name.isEmpty ())
432 fprintf (stderr,
"*** cannot create %s: %s\n",
441QString CppGenerator::debugInfoProt()
const
444 prot +=
grammar.table_name.toUpper();
445 prot +=
"_DEBUG_INFO"_L1;
454 <<
" enum VariousConstants {" <<
Qt::endl;
461 if (
name ==
"$end"_L1)
462 name =
"EOF_SYMBOL"_L1;
464 else if (
name ==
"$accept"_L1)
465 name =
"ACCEPT_SYMBOL"_L1;
474 <<
" ACCEPT_STATE = " << accept_state <<
"," <<
Qt::endl
476 <<
" STATE_COUNT = " << state_count <<
"," <<
Qt::endl
477 <<
" TERMINAL_COUNT = " << terminal_count <<
"," <<
Qt::endl
478 <<
" NON_TERMINAL_COUNT = " << non_terminal_count <<
"," <<
Qt::endl
481 <<
" GOTO_INFO_OFFSET = " << compressed_action.
info.
size () <<
"," <<
Qt::endl
485 <<
" static const char *const spell[];" <<
Qt::endl
486 <<
" static const short lhs[];" <<
Qt::endl
487 <<
" static const short rhs[];" <<
Qt::endl;
491 QString prot = debugInfoProt();
494 <<
" static const int rule_index[];" <<
Qt::endl
495 <<
" static const int rule_info[];" <<
Qt::endl
499 out <<
" static const short goto_default[];" <<
Qt::endl
500 <<
" static const short action_default[];" <<
Qt::endl
501 <<
" static const short action_index[];" <<
Qt::endl
502 <<
" static const short action_info[];" <<
Qt::endl
503 <<
" static const short action_check[];" <<
Qt::endl
505 <<
" static inline int nt_action (int state, int nt)" <<
Qt::endl
507 <<
" const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;" <<
Qt::endl
508 <<
" if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)" <<
Qt::endl
509 <<
" return goto_default [nt];" <<
Qt::endl
511 <<
" return action_info [GOTO_INFO_OFFSET + yyn];" <<
Qt::endl
514 <<
" static inline int t_action (int state, int token)" <<
Qt::endl
516 <<
" const int yyn = action_index [state] + token;" <<
Qt::endl
518 <<
" if (yyn < 0 || action_check [yyn] != token)" <<
Qt::endl
519 <<
" return - action_default [state];" <<
Qt::endl
521 <<
" return action_info [yyn];" <<
Qt::endl
532 out <<
"const char *const " <<
grammar.table_name <<
"::spell [] = {";
535 QMap<Name, int> name_ids;
536 bool first_nt =
true;
540 bool terminal =
grammar.isTerminal (
t);
542 if (! (debug_info || terminal))
545 name_ids.insert (
t, idx);
547 generateSeparator(idx,
out);
556 out <<
"\"" << spell <<
"\"";
563 QString prot = debugInfoProt();
566 out <<
"\"" << *
t <<
"\"";
575 out <<
"const short " <<
grammar.table_name <<
"::lhs [] = {";
579 generateSeparator(idx,
out);
585 out <<
"const short " <<
grammar.table_name <<
"::rhs [] = {";
589 generateSeparator(idx,
out);
597 QString prot = debugInfoProt();
600 out <<
"const int " <<
grammar.table_name <<
"::rule_info [] = {";
604 generateSeparator(idx,
out);
606 out << name_ids.value(
rule->lhs);
613 out <<
"const int " <<
grammar.table_name <<
"::rule_index [] = {";
618 generateSeparator(idx,
out);
627 out <<
"const short " <<
grammar.table_name <<
"::action_default [] = {";
631 generateSeparator(idx,
out);
640 out <<
"const short " <<
grammar.table_name <<
"::goto_default [] = {";
641 generateList(defgoto,
out);
644 out <<
"const short " <<
grammar.table_name <<
"::action_index [] = {";
645 generateList(compressed_action.
index,
out);
647 generateList(compressed_goto.
index,
out);
650 out <<
"const short " <<
grammar.table_name <<
"::action_info [] = {";
651 generateList(compressed_action.
info,
out);
653 generateList(compressed_goto.
info,
out);
656 out <<
"const short " <<
grammar.table_name <<
"::action_check [] = {";
657 generateList(compressed_action.
check,
out);
659 generateList(compressed_goto.
check,
out);
QMap< ItemPointer, NameSet > lookaheads
qsizetype size() const noexcept
void resize(qsizetype size)
T value(const Key &key, const T &defaultValue=T()) const
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString & replace(qsizetype i, qsizetype len, QChar after)
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
QString toUpper() const &
QT_BEGIN_NAMESPACE QTextStream & qerr()
ItemList::iterator ItemPointer
StateList::iterator StatePointer
std::list< QString >::iterator Name
debug_infot::iterator RulePointer
QTextStream & endl(QTextStream &stream)
Writes '\n' to the stream and flushes the stream.
DBusConnection const char * rule
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
constexpr const T & qMax(const T &a, const T &b)
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLenum GLsizei count
GLenum GLuint GLintptr offset
GLdouble GLdouble GLdouble GLdouble q
GLint GLenum GLboolean normalized
GLenum GLenum GLsizei void * table
#define qPrintable(string)
QTextStream out(stdout)
[7]
\inmodule QtCore \reentrant