Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ jobs:
<key>CFBundleExecutable</key>
<string>SyntaxTutor</string>
<key>CFBundleIdentifier</key>
<string>com.uma.syntaxtutor</string>
<string>me.jram.syntaxtutor</string>
<key>CFBundleVersion</key>
<string>${VERSION}</string>
<key>CFBundleShortVersionString</key>
Expand Down Expand Up @@ -218,10 +218,23 @@ jobs:
# GNU make would prefer over the qmake-generated Makefile.
make -f Makefile -j$(nproc)

- name: Install Wayland client libraries
# Needed so linuxdeploy can resolve the Qt Wayland plugin's
# dependencies. The libraries themselves stay out of the AppImage:
# every Wayland system has its own.
run: |
sudo apt-get update
sudo apt-get install -y libwayland-client0 libwayland-cursor0 libwayland-egl1

- name: Generate AppImage
run: |
export APPIMAGE_EXTRACT_AND_RUN=1
export LD_VER=continuous
# Ship the Wayland platform plugin next to X11 (xcb). The app still
# starts on X11 - through XWayland on a Wayland desktop - and uses
# Wayland only without an X server or with QT_QPA_PLATFORM=wayland
# (see main.cpp).
export EXTRA_PLATFORM_PLUGINS="libqwayland-egl.so;libqwayland-generic.so"
APPDIR=SyntaxTutor.AppDir

wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/${LD_VER}/linuxdeploy-x86_64.AppImage \
Expand Down
2 changes: 1 addition & 1 deletion APP_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.0.0-rc.7
2.0.0-rc.final
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ SyntaxTutor walks the student through each cell in the parsing table with hints

## 📦 Downloads
Precompiled builds of SyntaxTutor are available in the Releases tab:
- 🐧 Linux (X11): executable AppImage
- 🐧 Linux: executable AppImage (Ubuntu 22.04, Debian 12 or newer). It runs on X11, and on
Wayland desktops through XWayland; to run it natively on Wayland, start it with
`QT_QPA_PLATFORM=wayland ./SyntaxTutor-<version>-x86_64.AppImage`
- 🪟 Windows: ZIP archive with the .exe
- 🍎 macOS: .app bundle for Apple Silicon (ARM)

Expand Down
3 changes: 3 additions & 0 deletions SyntaxTutor.pro
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,13 @@ HEADERS += \
src/widgets/appicon.h \
src/widgets/applayout.h \
src/widgets/apppalette.h \
src/widgets/appsettings.h \
src/widgets/appshortcuts.h \
src/widgets/automatonview.h \
src/widgets/customtextedit.h \
src/widgets/grammarview.h \
src/gui/automatonviewerdialog.h \
src/gui/conversationpdf.h \
src/gui/examreportdialog.h \
src/gui/examsession.h \
src/gui/grammareditordialog.h \
Expand All @@ -88,6 +90,7 @@ FORMS += \

win32: RC_ICONS = resources/icon/syntaxtutor.ico
macx: ICON = resources/icon/syntaxtutor.icns
macx: QMAKE_TARGET_BUNDLE_PREFIX = me.jram

win32:CONFIG(release, debug|release) {
msvc {
Expand Down
2 changes: 1 addition & 1 deletion resources/icon/lockup/syntaxtutor-lockup-dark-text.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion resources/icon/lockup/syntaxtutor-lockup-light-text.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/icon/png/syntaxtutor-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/icon/png/syntaxtutor-16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/icon/png/syntaxtutor-24.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/icon/png/syntaxtutor-256.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/icon/png/syntaxtutor-32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/icon/png/syntaxtutor-48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/icon/png/syntaxtutor-512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/icon/png/syntaxtutor-64.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/icon/syntaxtutor.icns
Binary file not shown.
Binary file modified resources/icon/syntaxtutor.ico
Binary file not shown.
2 changes: 1 addition & 1 deletion resources/icon/syntaxtutor.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion resources/styles/app.qss
Original file line number Diff line number Diff line change
Expand Up @@ -1011,7 +1011,7 @@ QGraphicsView#llDerivationTreeView {
}

QDialog[automatonViewer="true"] QLabel#automatonViewerHint {
color: #6F7A7E;
color: #9AA5A8;
font-size: $font-label;
}

Expand Down
14 changes: 12 additions & 2 deletions src/app/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "appversion.h"
#include "appicon.h"
#include "appsettings.h"
#include "apppalette.h"
#include "apptypography.h"
#include "mainwindow.h"
Expand All @@ -37,6 +38,15 @@ void applyAppStyle(QApplication& app) {
}

int main(int argc, char* argv[]) {
#ifdef Q_OS_LINUX
// X11 first - through XWayland on a Wayland desktop, the tested path -
// and native Wayland only where there is no X server. Without this, Qt
// picks Wayland on its own as soon as its plugin is present. Native
// Wayland can still be asked for with QT_QPA_PLATFORM=wayland.
if (!qEnvironmentVariableIsSet("QT_QPA_PLATFORM")) {
qputenv("QT_QPA_PLATFORM", "xcb;wayland");
}
#endif
QApplication a(argc, argv);
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
QGuiApplication::styleHints()->setColorScheme(Qt::ColorScheme::Dark);
Expand All @@ -51,10 +61,10 @@ int main(int argc, char* argv[]) {
QFontDatabase::addApplicationFont(
":/resources/fonts/JetBrainsMono-Bold.ttf");
#endif
QCoreApplication::setApplicationName("SyntaxTutor");
AppSettings::registerIdentity();
QGuiApplication::setApplicationDisplayName("SyntaxTutor");
QCoreApplication::setApplicationVersion(SyntaxTutor::Version::current());
QSettings settings("UMA", "SyntaxTutor");
QSettings settings = AppSettings::open();
if (settings.contains(AppTextScale::settingsKey())) {
AppTextScale::currentPercent() = AppTextScale::clampPercent(
settings.value(AppTextScale::settingsKey()).toInt());
Expand Down
4 changes: 2 additions & 2 deletions src/appversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

namespace SyntaxTutor::Version {
inline QString current() {
return QStringLiteral("2.0.0-rc.7");
return QStringLiteral("2.0.0-rc.final");
}

inline const char* raw() {
return "2.0.0-rc.7";
return "2.0.0-rc.final";
}
} // namespace SyntaxTutor::Version
#endif // APPVERSION_H
9 changes: 9 additions & 0 deletions src/backend/slr1_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,15 @@ bool SLR1Parser::SolveLRConflicts(const state& st) {
if (item.IsComplete()) {
// Regla 3: Si el ítem es del axioma, ACCEPT en EOL
if (item.antecedent_ == gr_.axiom_) {
// A reduction already written on EOL collides with accepting
// (ACCEPT/REDUCE). Overwriting it hid the conflict whenever
// the reduction happened to be visited first, which depends
// on the item set's iteration order.
auto it = actions_[st.id_].find(gr_.st_.EOL_);
if (it != actions_[st.id_].end() &&
it->second.action != Action::Accept) {
return false;
}
actions_[st.id_][gr_.st_.EOL_] = {nullptr, Action::Accept};
} else {
// Regla 2: Si el ítem es completo, REDUCE en FOLLOW(A)
Expand Down
49 changes: 49 additions & 0 deletions src/backend/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3796,3 +3796,52 @@ int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

// Accepting is the action for the axiom's item S -> A . $ on $. When the
// same state also reduces another rule on $, the two collide: the grammar is
// not SLR(1). The accept entry used to be written without looking at what
// the cell held, so a reduction already there was silently replaced and the
// grammar passed as SLR(1). Whether the reduction was written first depends
// on the iteration order of the item set, which differs between standard
// libraries: the list mixes grammars that slipped through on macOS and on
// Linux.
TEST(SLR1_AcceptConflict, AcceptAndReduceOnEndOfInputIsNotSlr1) {
const char* grammars[] = {
"A -> A B | .\nB -> .",
"A -> A B | B b .\nB -> .",
"A -> C C | A C .\nB -> a A | c .\nC -> A .",
"A -> C | b | A B .\nB -> C a | C B | .\nC -> C c .",
"A -> B | A .\nB -> b b | a | c c .",
};
for (const char* text : grammars) {
const GrammarParseResult parsed = GrammarParser::Parse(text);
ASSERT_TRUE(parsed.Ok()) << text;
SLR1Parser slr1(parsed.grammar);
EXPECT_FALSE(slr1.MakeParser()) << text;
}
}

// The same state accepting on $ and reducing on other symbols is fine.
TEST(SLR1_AcceptConflict, AcceptBesideReductionOnOtherSymbolsIsSlr1) {
const GrammarParseResult parsed =
GrammarParser::Parse("A -> B c | d .\nB -> A .");
ASSERT_TRUE(parsed.Ok());
SLR1Parser slr1(parsed.grammar);
ASSERT_TRUE(slr1.MakeParser());

const Grammar& g = slr1.gr_;
bool found = false;
for (const auto& [id, row] : slr1.actions_) {
const auto eol = row.find(g.st_.EOL_);
const auto c = row.find("c");
const bool accepts =
eol != row.end() && eol->second.action == SLR1Parser::Action::Accept;
const bool reduces =
c != row.end() && c->second.action == SLR1Parser::Action::Reduce;
if (accepts && reduces) {
EXPECT_EQ(c->second.item->antecedent_, "B");
found = true;
}
}
EXPECT_TRUE(found);
}
Loading
Loading