9#include <QtCore/qbitarray.h>
10#include <QtCore/qtextstream.h>
11#include <QtCore/qfile.h>
12#include <QtCore/qmap.h>
13#include <QtCore/private/qconfig_p.h>
35 generateSeparator(
i,
out);
43QString CppGenerator::copyrightHeader()
const
46 "// " QT_COPYRIGHT
"\n"
47 "// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0\n"
51QString CppGenerator::privateCopyrightHeader()
const
58 "// This file is not part of the Qt API. It exists for the convenience\n"
59 "// of other Qt classes. This header file may change from version to\n"
60 "// version without notice, or even be removed.\n"
84 state_count =
static_cast<int>(aut.
states.size());
85 terminal_count =
static_cast<int>(
grammar.terminals.size());
86 non_terminal_count =
static_cast<int>(
grammar.non_terminals.size());
88#define ACTION(i, j) table [(i) * terminal_count + (j)]
89#define GOTO(i, j) pgoto [(i) * non_terminal_count + (j)]
91 int *
table =
new int [state_count * terminal_count];
92 ::memset (
table, 0, state_count * terminal_count *
sizeof (
int));
94 int *pgoto =
new int [state_count * non_terminal_count];
95 ::memset (pgoto, 0, state_count * non_terminal_count *
sizeof (
int));
98 int shift_reduce_conflict_count = 0;
99 int reduce_reduce_conflict_count = 0;
105 for (Bundle::iterator
a =
state->bundle.begin ();
a !=
state->bundle.end (); ++
a)
107 int symbol = aut.
id (
a.key ());
108 int r = aut.
id (
a.value ());
112 if (
grammar.isNonTerminal (
a.key ()))
114 Q_ASSERT(symbol >= terminal_count && symbol <
static_cast<int>(
grammar.names.size()));
115 GOTO (
q, symbol - terminal_count) =
r;
134 for (
const Name &
s : lookaheads)
144 qout() <<
"*** Warning. Found a reduce/reduce conflict in state " <<
q <<
" on token ``" <<
s <<
"'' between rule "
147 ++reduce_reduce_conflict_count;
164 else if (info_r.
prec == info_s.
prec)
166 switch (info_r.
assoc) {
182 ++shift_reduce_conflict_count;
185 qout() <<
"*** Warning. Found a shift/reduce conflict in state " <<
q <<
" on token ``" <<
s <<
"'' with rule " <<
r <<
Qt::endl;
192 if (shift_reduce_conflict_count || reduce_reduce_conflict_count)
194 if (shift_reduce_conflict_count !=
grammar.expected_shift_reduce
195 || reduce_reduce_conflict_count !=
grammar.expected_reduce_reduce)
197 qerr() <<
"*** Conflicts: " << shift_reduce_conflict_count <<
" shift/reduce, " << reduce_reduce_conflict_count <<
" reduce/reduce" <<
Qt::endl;
198 if (warnings_are_errors)
200 qerr() <<
"qlalr: error: warning occurred, treating as error due to "
207 qout() <<
Qt::endl <<
"*** Conflicts: " << shift_reduce_conflict_count <<
" shift/reduce, " << reduce_reduce_conflict_count <<
" reduce/reduce" <<
Qt::endl
216 for (
int j = 0;
j < terminal_count; ++
j)
221 used_rules.setBit (-u - 1);
226 for (
int i = 0;
i < used_rules.size(); ++
i, ++
rule)
228 if (! used_rules.testBit (
i))
233 if (warnings_are_errors)
235 qerr() <<
"qlalr: error: warning occurred, treating as error due to "
246 for (
int j = 0;
j < terminal_count; ++
j)
261 defgoto.
resize (non_terminal_count);
262 for (
int j = 0;
j < non_terminal_count; ++
j)
264 count.fill (0, state_count);
266 int &mx = defgoto [
j];
268 for (
int i = 0;
i < state_count; ++
i)
282 for (
int i = 0;
i < state_count; ++
i)
284 for (
int j = 0;
j < non_terminal_count; ++
j)
288 if (
r == defgoto [
j])
293 compressed_action (
table, state_count, terminal_count);
294 compressed_goto (pgoto, state_count, non_terminal_count);
305 if (!
grammar.merged_output.isEmpty())
319 out << copyrightHeader()
320 << privateCopyrightHeader()
324 out <<
"// This file was generated by qlalr - DO NOT EDIT!\n";
359 out << copyrightHeader()
360 << privateCopyrightHeader()
364 out <<
"// This file was generated by qlalr - DO NOT EDIT!\n";
388 out << copyrightHeader();
390 out <<
"// This file was generated by qlalr - DO NOT EDIT!\n";
401 if (!
grammar.decl_file_name.isEmpty ())
409 if (!
grammar.impl_file_name.isEmpty ())
418QString CppGenerator::debugInfoProt()
const
421 prot +=
grammar.table_name.toUpper();
422 prot +=
"_DEBUG_INFO"_L1;
431 <<
" enum VariousConstants {" <<
Qt::endl;
438 if (
name ==
"$end"_L1)
439 name =
"EOF_SYMBOL"_L1;
441 else if (
name ==
"$accept"_L1)
442 name =
"ACCEPT_SYMBOL"_L1;
451 <<
" ACCEPT_STATE = " << accept_state <<
"," <<
Qt::endl
453 <<
" STATE_COUNT = " << state_count <<
"," <<
Qt::endl
454 <<
" TERMINAL_COUNT = " << terminal_count <<
"," <<
Qt::endl
455 <<
" NON_TERMINAL_COUNT = " << non_terminal_count <<
"," <<
Qt::endl
458 <<
" GOTO_INFO_OFFSET = " << compressed_action.
info.
size () <<
"," <<
Qt::endl
462 <<
" static const char *const spell[];" <<
Qt::endl
463 <<
" static const short lhs[];" <<
Qt::endl
464 <<
" static const short rhs[];" <<
Qt::endl;
468 QString prot = debugInfoProt();
471 <<
" static const int rule_index[];" <<
Qt::endl
472 <<
" static const int rule_info[];" <<
Qt::endl
476 out <<
" static const short goto_default[];" <<
Qt::endl
477 <<
" static const short action_default[];" <<
Qt::endl
478 <<
" static const short action_index[];" <<
Qt::endl
479 <<
" static const short action_info[];" <<
Qt::endl
480 <<
" static const short action_check[];" <<
Qt::endl
482 <<
" static inline int nt_action (int state, int nt)" <<
Qt::endl
484 <<
" const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;" <<
Qt::endl
485 <<
" if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)" <<
Qt::endl
486 <<
" return goto_default [nt];" <<
Qt::endl
488 <<
" return action_info [GOTO_INFO_OFFSET + yyn];" <<
Qt::endl
491 <<
" static inline int t_action (int state, int token)" <<
Qt::endl
493 <<
" const int yyn = action_index [state] + token;" <<
Qt::endl
495 <<
" if (yyn < 0 || action_check [yyn] != token)" <<
Qt::endl
496 <<
" return - action_default [state];" <<
Qt::endl
498 <<
" return action_info [yyn];" <<
Qt::endl
509 out <<
"const char *const " <<
grammar.table_name <<
"::spell [] = {";
513 bool first_nt =
true;
517 bool terminal =
grammar.isTerminal (
t);
519 if (! (debug_info || terminal))
524 generateSeparator(idx,
out);
533 out <<
"\"" << spell <<
"\"";
540 QString prot = debugInfoProt();
543 out <<
"\"" << *
t <<
"\"";
552 out <<
"const short " <<
grammar.table_name <<
"::lhs [] = {";
556 generateSeparator(idx,
out);
562 out <<
"const short " <<
grammar.table_name <<
"::rhs [] = {";
566 generateSeparator(idx,
out);
574 QString prot = debugInfoProt();
577 out <<
"const int " <<
grammar.table_name <<
"::rule_info [] = {";
581 generateSeparator(idx,
out);
590 out <<
"const int " <<
grammar.table_name <<
"::rule_index [] = {";
595 generateSeparator(idx,
out);
604 out <<
"const short " <<
grammar.table_name <<
"::action_default [] = {";
608 generateSeparator(idx,
out);
617 out <<
"const short " <<
grammar.table_name <<
"::goto_default [] = {";
618 generateList(defgoto,
out);
621 out <<
"const short " <<
grammar.table_name <<
"::action_index [] = {";
622 generateList(compressed_action.
index,
out);
624 generateList(compressed_goto.
index,
out);
627 out <<
"const short " <<
grammar.table_name <<
"::action_info [] = {";
628 generateList(compressed_action.
info,
out);
630 generateList(compressed_goto.
info,
out);
633 out <<
"const short " <<
grammar.table_name <<
"::action_check [] = {";
634 generateList(compressed_action.
check,
out);
636 generateList(compressed_goto.
check,
out);
QMap< ItemPointer, NameSet > lookaheads
qsizetype size() const noexcept
void resize(qsizetype size)
iterator insert(const Key &key, const T &value)
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...
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
bool isEmpty() const
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