aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@qt.io>2018-04-30 14:50:03 +0200
committerJoerg Bornemann <joerg.bornemann@qt.io>2018-05-04 05:19:20 +0000
commit2319531641817ef7d96a212b02aa0e763419fb00 (patch)
tree22e3d5243c96f28ac42e8fcc07d4e7d759fcc4fa /tests
parent9258beb35aaf30ab2e89cdd6af0e02ddc179d98d (diff)
Add support for prefix/output in lex_yacc module
The user can specify the outputs of lex/yacc via %option prefix="foo" in the .l file and %output "parser.cpp" in the .y file. Also, introduce the following properties to specify the outputs: lexOutputFilePath, yaccOutputFilePath. Scan the lex/yacc inputs for those specifications and adjust the output artifacts accordingly. [ChangeLog] Added support for %option outfile and %output to the lex_yacc module. Change-Id: I5437c737ae8da54dc7eda81ac7384727f00f9d1f Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/blackbox/testdata/lexyacc/lex_outfile/lex_outfile.qbs16
-rw-r--r--tests/auto/blackbox/testdata/lexyacc/lex_outfile/lexer.l21
-rw-r--r--tests/auto/blackbox/testdata/lexyacc/lex_outfile/parser.y30
-rw-r--r--tests/auto/blackbox/testdata/lexyacc/lex_outfile/types.h50
-rw-r--r--tests/auto/blackbox/testdata/lexyacc/lex_prefix/lex_prefix.qbs16
-rw-r--r--tests/auto/blackbox/testdata/lexyacc/lex_prefix/lexer.l21
-rw-r--r--tests/auto/blackbox/testdata/lexyacc/lex_prefix/parser.y31
-rw-r--r--tests/auto/blackbox/testdata/lexyacc/lex_prefix/types.h50
-rw-r--r--tests/auto/blackbox/testdata/lexyacc/yacc_output/lexer.l21
-rw-r--r--tests/auto/blackbox/testdata/lexyacc/yacc_output/parser.y31
-rw-r--r--tests/auto/blackbox/testdata/lexyacc/yacc_output/types.h50
-rw-r--r--tests/auto/blackbox/testdata/lexyacc/yacc_output/yacc_output.qbs16
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp62
-rw-r--r--tests/auto/blackbox/tst_blackbox.h3
14 files changed, 415 insertions, 3 deletions
diff --git a/tests/auto/blackbox/testdata/lexyacc/lex_outfile/lex_outfile.qbs b/tests/auto/blackbox/testdata/lexyacc/lex_outfile/lex_outfile.qbs
new file mode 100644
index 000000000..677828906
--- /dev/null
+++ b/tests/auto/blackbox/testdata/lexyacc/lex_outfile/lex_outfile.qbs
@@ -0,0 +1,16 @@
+import qbs
+
+CppApplication {
+ Depends { name: "lex_yacc" }
+ lex_yacc.outputTag: "cpp"
+ lex_yacc.yaccFlags: ["-l"]
+ cpp.includePaths: ["."]
+ cpp.cxxLanguageVersion: "c++11"
+ cpp.minimumMacosVersion: "10.7"
+ consoleApplication: true
+ files: [
+ "lexer.l",
+ "parser.y",
+ "types.h",
+ ]
+}
diff --git a/tests/auto/blackbox/testdata/lexyacc/lex_outfile/lexer.l b/tests/auto/blackbox/testdata/lexyacc/lex_outfile/lexer.l
new file mode 100644
index 000000000..07115405d
--- /dev/null
+++ b/tests/auto/blackbox/testdata/lexyacc/lex_outfile/lexer.l
@@ -0,0 +1,21 @@
+%option outfile="quark.cpp"
+%{
+#include <types.h>
+void yyerror(const char *e) { std::cerr << e; }
+extern "C" int yywrap() { return 1; }
+extern YYSTYPE yylval;
+%}
+
+ID [a-z]+
+AND "&&"
+OR "||"
+NOT "!"
+
+%%
+[[:space:]]+
+{ID} yylval.s = yytext; return 1;
+{AND} return 2;
+{OR} return 3;
+{NOT} return 4;
+
+%%
diff --git a/tests/auto/blackbox/testdata/lexyacc/lex_outfile/parser.y b/tests/auto/blackbox/testdata/lexyacc/lex_outfile/parser.y
new file mode 100644
index 000000000..e19c9a90b
--- /dev/null
+++ b/tests/auto/blackbox/testdata/lexyacc/lex_outfile/parser.y
@@ -0,0 +1,30 @@
+%{
+#include <types.h>
+%}
+
+%type <t> expr
+%left OR
+%left AND
+%nonassoc NOT
+%token <s> ID
+
+%%
+
+start: expr { root = $1; }
+expr: expr AND expr { auto t = std::make_shared<Tree>(); t->val = "AND"; t->children = { $1, $3 }; $$ = t; }
+ | expr OR expr { auto t = std::make_shared<Tree>(); t->val = "OR"; t->children = { $1, $3 }; $$ = t; }
+ | NOT expr { auto t = std::make_shared<Tree>(); t->val = "NOT"; t->children = { $2 }; $$ = t; }
+ | ID { auto t = std::make_shared<Tree>(); t->val = $1; $$ = t; }
+
+%%
+
+TreePtr root;
+
+int main()
+{
+ yyparse();
+ if (!root)
+ return 1;
+ root->print();
+ std::cout << std::endl;
+}
diff --git a/tests/auto/blackbox/testdata/lexyacc/lex_outfile/types.h b/tests/auto/blackbox/testdata/lexyacc/lex_outfile/types.h
new file mode 100644
index 000000000..12cafe890
--- /dev/null
+++ b/tests/auto/blackbox/testdata/lexyacc/lex_outfile/types.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <iostream>
+#include <memory>
+#include <string>
+#include <vector>
+
+struct Tree;
+using TreePtr = std::shared_ptr<Tree>;
+struct Tree {
+ std::string val;
+ std::vector<TreePtr> children;
+ void print() const {
+ std::cout << val << ' ';
+ for (const TreePtr &t : children)
+ t->print();
+ }
+};
+struct YaccType { TreePtr t; std::string s; };
+#define YYSTYPE YaccType
+extern TreePtr root;
+
+int yylex();
+void yyerror(const char *);
diff --git a/tests/auto/blackbox/testdata/lexyacc/lex_prefix/lex_prefix.qbs b/tests/auto/blackbox/testdata/lexyacc/lex_prefix/lex_prefix.qbs
new file mode 100644
index 000000000..677828906
--- /dev/null
+++ b/tests/auto/blackbox/testdata/lexyacc/lex_prefix/lex_prefix.qbs
@@ -0,0 +1,16 @@
+import qbs
+
+CppApplication {
+ Depends { name: "lex_yacc" }
+ lex_yacc.outputTag: "cpp"
+ lex_yacc.yaccFlags: ["-l"]
+ cpp.includePaths: ["."]
+ cpp.cxxLanguageVersion: "c++11"
+ cpp.minimumMacosVersion: "10.7"
+ consoleApplication: true
+ files: [
+ "lexer.l",
+ "parser.y",
+ "types.h",
+ ]
+}
diff --git a/tests/auto/blackbox/testdata/lexyacc/lex_prefix/lexer.l b/tests/auto/blackbox/testdata/lexyacc/lex_prefix/lexer.l
new file mode 100644
index 000000000..cbbc79fbc
--- /dev/null
+++ b/tests/auto/blackbox/testdata/lexyacc/lex_prefix/lexer.l
@@ -0,0 +1,21 @@
+%option prefix="bla"
+%{
+#include <types.h>
+void blaerror(const char *e) { std::cerr << e; }
+extern "C" int blawrap() { return 1; }
+extern BLASTYPE blalval;
+%}
+
+ID [a-z]+
+AND "&&"
+OR "||"
+NOT "!"
+
+%%
+[[:space:]]+
+{ID} blalval.s = blatext; return 1;
+{AND} return 2;
+{OR} return 3;
+{NOT} return 4;
+
+%%
diff --git a/tests/auto/blackbox/testdata/lexyacc/lex_prefix/parser.y b/tests/auto/blackbox/testdata/lexyacc/lex_prefix/parser.y
new file mode 100644
index 000000000..17ec6700b
--- /dev/null
+++ b/tests/auto/blackbox/testdata/lexyacc/lex_prefix/parser.y
@@ -0,0 +1,31 @@
+%{
+#include <types.h>
+%}
+
+%define api.prefix {bla}
+%type <t> expr
+%left OR
+%left AND
+%nonassoc NOT
+%token <s> ID
+
+%%
+
+start: expr { root = $1; }
+expr: expr AND expr { auto t = std::make_shared<Tree>(); t->val = "AND"; t->children = { $1, $3 }; $$ = t; }
+ | expr OR expr { auto t = std::make_shared<Tree>(); t->val = "OR"; t->children = { $1, $3 }; $$ = t; }
+ | NOT expr { auto t = std::make_shared<Tree>(); t->val = "NOT"; t->children = { $2 }; $$ = t; }
+ | ID { auto t = std::make_shared<Tree>(); t->val = $1; $$ = t; }
+
+%%
+
+TreePtr root;
+
+int main()
+{
+ blaparse();
+ if (!root)
+ return 1;
+ root->print();
+ std::cout << std::endl;
+}
diff --git a/tests/auto/blackbox/testdata/lexyacc/lex_prefix/types.h b/tests/auto/blackbox/testdata/lexyacc/lex_prefix/types.h
new file mode 100644
index 000000000..e0682141c
--- /dev/null
+++ b/tests/auto/blackbox/testdata/lexyacc/lex_prefix/types.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <iostream>
+#include <memory>
+#include <string>
+#include <vector>
+
+struct Tree;
+using TreePtr = std::shared_ptr<Tree>;
+struct Tree {
+ std::string val;
+ std::vector<TreePtr> children;
+ void print() const {
+ std::cout << val << ' ';
+ for (const TreePtr &t : children)
+ t->print();
+ }
+};
+struct YaccType { TreePtr t; std::string s; };
+#define BLASTYPE YaccType
+extern TreePtr root;
+
+int blalex();
+void blaerror(const char *);
diff --git a/tests/auto/blackbox/testdata/lexyacc/yacc_output/lexer.l b/tests/auto/blackbox/testdata/lexyacc/yacc_output/lexer.l
new file mode 100644
index 000000000..600ff2832
--- /dev/null
+++ b/tests/auto/blackbox/testdata/lexyacc/yacc_output/lexer.l
@@ -0,0 +1,21 @@
+%{
+#include <types.h>
+#include <parser.hxx>
+void yyerror(const char *e) { std::cerr << e; }
+extern "C" int yywrap() { return 1; }
+extern YYSTYPE yylval;
+%}
+
+ID [a-z]+
+AND "&&"
+OR "||"
+NOT "!"
+
+%%
+[[:space:]]+
+{ID} yylval.s = yytext; return ID;
+{AND} return AND;
+{OR} return OR;
+{NOT} return NOT;
+
+%%
diff --git a/tests/auto/blackbox/testdata/lexyacc/yacc_output/parser.y b/tests/auto/blackbox/testdata/lexyacc/yacc_output/parser.y
new file mode 100644
index 000000000..111e20bc5
--- /dev/null
+++ b/tests/auto/blackbox/testdata/lexyacc/yacc_output/parser.y
@@ -0,0 +1,31 @@
+%{
+#include <types.h>
+%}
+
+%output "parser.cxx"
+%type <t> expr
+%left OR
+%left AND
+%nonassoc NOT
+%token <s> ID
+
+%%
+
+start: expr { root = $1; }
+expr: expr AND expr { auto t = std::make_shared<Tree>(); t->val = "AND"; t->children = { $1, $3 }; $$ = t; }
+ | expr OR expr { auto t = std::make_shared<Tree>(); t->val = "OR"; t->children = { $1, $3 }; $$ = t; }
+ | NOT expr { auto t = std::make_shared<Tree>(); t->val = "NOT"; t->children = { $2 }; $$ = t; }
+ | ID { auto t = std::make_shared<Tree>(); t->val = $1; $$ = t; }
+
+%%
+
+TreePtr root;
+
+int main()
+{
+ yyparse();
+ if (!root)
+ return 1;
+ root->print();
+ std::cout << std::endl;
+}
diff --git a/tests/auto/blackbox/testdata/lexyacc/yacc_output/types.h b/tests/auto/blackbox/testdata/lexyacc/yacc_output/types.h
new file mode 100644
index 000000000..12cafe890
--- /dev/null
+++ b/tests/auto/blackbox/testdata/lexyacc/yacc_output/types.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <iostream>
+#include <memory>
+#include <string>
+#include <vector>
+
+struct Tree;
+using TreePtr = std::shared_ptr<Tree>;
+struct Tree {
+ std::string val;
+ std::vector<TreePtr> children;
+ void print() const {
+ std::cout << val << ' ';
+ for (const TreePtr &t : children)
+ t->print();
+ }
+};
+struct YaccType { TreePtr t; std::string s; };
+#define YYSTYPE YaccType
+extern TreePtr root;
+
+int yylex();
+void yyerror(const char *);
diff --git a/tests/auto/blackbox/testdata/lexyacc/yacc_output/yacc_output.qbs b/tests/auto/blackbox/testdata/lexyacc/yacc_output/yacc_output.qbs
new file mode 100644
index 000000000..677828906
--- /dev/null
+++ b/tests/auto/blackbox/testdata/lexyacc/yacc_output/yacc_output.qbs
@@ -0,0 +1,16 @@
+import qbs
+
+CppApplication {
+ Depends { name: "lex_yacc" }
+ lex_yacc.outputTag: "cpp"
+ lex_yacc.yaccFlags: ["-l"]
+ cpp.includePaths: ["."]
+ cpp.cxxLanguageVersion: "c++11"
+ cpp.minimumMacosVersion: "10.7"
+ consoleApplication: true
+ files: [
+ "lexer.l",
+ "parser.y",
+ "types.h",
+ ]
+}
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index 75721370c..e548a0236 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -144,6 +144,12 @@ QString TestBlackbox::findArchiver(const QString &fileName, int *status)
return binary;
}
+bool TestBlackbox::lexYaccExist()
+{
+ return !findExecutable(QStringList("lex")).isEmpty()
+ && !findExecutable(QStringList("yacc")).isEmpty();
+}
+
void TestBlackbox::sevenZip()
{
QDir::setCurrent(testDataDir + "/archiver");
@@ -3910,10 +3916,8 @@ void TestBlackbox::linkerMode()
void TestBlackbox::lexyacc()
{
- if (findExecutable(QStringList("lex")).isEmpty()
- || findExecutable(QStringList("yacc")).isEmpty()) {
+ if (!lexYaccExist())
QSKIP("lex or yacc not present");
- }
QDir::setCurrent(testDataDir + "/lexyacc/one-grammar");
QCOMPARE(runQbs(), 0);
const QString parserBinary = relativeExecutableFilePath("one-grammar");
@@ -3944,6 +3948,58 @@ void TestBlackbox::lexyacc()
QVERIFY2(m_qbsStderr.contains("whatever"), m_qbsStderr.constData());
}
+void TestBlackbox::lexyaccOutputs()
+{
+ if (!lexYaccExist())
+ QSKIP("lex or yacc not present");
+
+ QFETCH(QString, lexOutputFilePath);
+ QFETCH(QString, yaccOutputFilePath);
+ QbsRunParameters params;
+ if (!lexOutputFilePath.isEmpty())
+ params.arguments << "modules.lex_yacc.lexOutputFilePath:" + lexOutputFilePath;
+ if (!yaccOutputFilePath.isEmpty())
+ params.arguments << "modules.lex_yacc.yaccOutputFilePath:" + yaccOutputFilePath;
+
+#define VERIFY_COMPILATION(file) \
+ if (!file.isEmpty()) { \
+ QByteArray expected = "compiling " + file.toUtf8(); \
+ if (!m_qbsStdout.contains(expected)) { \
+ qDebug() << "Expected output:" << expected; \
+ qDebug() << "Actual output:" << m_qbsStdout; \
+ QFAIL("Expected stdout content missing."); \
+ } \
+ }
+
+ QVERIFY(QDir::setCurrent(testDataDir + "/lexyacc/lex_prefix"));
+ rmDirR(relativeBuildDir());
+ QCOMPARE(runQbs(params), 0);
+ VERIFY_COMPILATION(yaccOutputFilePath);
+
+ QVERIFY(QDir::setCurrent(testDataDir + "/lexyacc/lex_outfile"));
+ rmDirR(relativeBuildDir());
+ QCOMPARE(runQbs(params), 0);
+ VERIFY_COMPILATION(yaccOutputFilePath);
+
+ QVERIFY(QDir::setCurrent(testDataDir + "/lexyacc/yacc_output"));
+ rmDirR(relativeBuildDir());
+ QCOMPARE(runQbs(params), 0);
+ VERIFY_COMPILATION(lexOutputFilePath);
+
+#undef VERIFY_COMPILATION
+}
+
+void TestBlackbox::lexyaccOutputs_data()
+{
+ QTest::addColumn<QString>("lexOutputFilePath");
+ QTest::addColumn<QString>("yaccOutputFilePath");
+ QTest::newRow("none") << QString() << QString();
+ QTest::newRow("lexOutputFilePath")
+ << QString{"lex_luthor.cpp"} << QString();
+ QTest::newRow("yaccOutputFilePath")
+ << QString() << QString{"shaven_yak.cpp"};
+}
+
void TestBlackbox::linkerScripts()
{
const SettingsPtr s = settings();
diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h
index ac515d0c0..746c885fa 100644
--- a/tests/auto/blackbox/tst_blackbox.h
+++ b/tests/auto/blackbox/tst_blackbox.h
@@ -145,6 +145,8 @@ private slots:
void ld();
void linkerMode();
void lexyacc();
+ void lexyaccOutputs();
+ void lexyaccOutputs_data();
void linkerScripts();
void listProducts();
void listPropertiesWithOuter();
@@ -267,6 +269,7 @@ private:
QMap<QString, QString> findNodejs(int *status);
QMap<QString, QString> findTypeScript(int *status);
QString findArchiver(const QString &fileName, int *status = nullptr);
+ static bool lexYaccExist();
};
#endif // TST_BLACKBOX_H