About

This is an informational web page for the Compiler Principles course (NSWI098), which is being taught at the Faculty of Mathematics and Physics, Charles University.

You can find here:

Tutorials

Although the course is nominally 2/2 hours weekly, the tutorials will happen only once every two weeks. The students are encouraged to spend the remaining time doing experiments with an existing compiler of (a subset of) the C language, mostly by trying to implement some language features missing in the existing implementation. The teachers will explain the environment and try to organize the work at the tutorials. The experiments are best done in small groups, allowing discussions and dividing the workload. Because of the group work and possible AI support, the experiments will NOT be formally assigned as homework or awarded by credits.

Warning for Erasmus students

This course is tough. All Erasmus students who tried this course failed. That is why this course is not offered for Erasmus.

English-language students from the Charles University

The lecture is not offered in English because the course is not a recommended part of any of the English-language programmes.

Nevertheless, as a support for adventurous students of the English programmes, all the materials for the course are in English. In the history of the course, there were so far 2 English-language students who passed.

Contact

The course is currently led by David Bednárek. and Miroslav Kratochvíl.

Credits

There will be a practical test in December, as part of the tutorials. Those who fail will have another opportunity in January. Success in the practical test is required for enrolling to the exam.

The exam is oral with a time for written preparation.

Lectures

The dates below are only an approximation; actual timing will differ. The contents of slides may be adjusted just before every lecture.

29.9.2025 Compiler - an introduction PPTX File Icon 01-comp.pptx
6.10.2025 Lexical analysis PPTX File Icon 02-la.pptx
13.10.2025 Syntax analysis - an introduction PPTX File Icon 03-sxa.pptx
20.10.2025 Syntax analysis - top-down parsing PPTX File Icon 03-sxa.pptx
27.10.2025 Syntax analysis - bottom-up parsing PPTX File Icon 03-sxa.pptx
3.11.2025 Semantic analysis PPTX File Icon 05-saatr.pptx
10.11.2025 Intermediate code PPTX File Icon 04-ic.pptx
24.11.2025 Intermediate code generation PPTX File Icon 06-genic.pptx
1.12.2025 High-level optimizations PPTX File Icon 07-opt.pptx
8.12.2025 CPU architectures PPTX File Icon 08-cpu.pptx
15.12.2025 Code generation PPTX File Icon 08-cpu.pptx
5.1.2026 Runtime PPTX File Icon 09-rt.pptx
Interpreted languages PPTX File Icon 10-interp.pptx

Playground

In the previous seasons of this course, students were required to implement their own compiler of a subset of the C language. As the playground, you will receive the teachers' implementation of this compiler. The following paragraphs describe the main elements of the implementation.

Syntax of the language

The grammar rules of the subset are in the doc/selected-grammar.md in the skeleton repository. This grammar was created by removing some rules from the C programming language specification (working draft) Annex A.

Lexical analysis

Parsing

Slides (en): PPTX PDF

Declarations

Slides (en): PPTX PDF

Framework doxymentation

Frequently asked questions

Expressions

Slides (en): PPTX PDF

Framework doxymentation

Frequently asked questions

Control-flow statements and Boolean expressions

Slides (en): PPTX PDF

Framework doxymentation

Developing and testing

Read the Using your Cecko repository section before cloning the skeleton. The framework and skeleton files may be updated for various reasons, therefore, you will need a method to merge the updates into your project.

The skeleton framework contains the following folders:

You will need to prepare your building environment as described in Prerequisites.

Refer to Building and running Cecko for instructions on building and running the code.

The solution files

Test files

The Cecko source files have the usual suffix .c, the corresponding expected outputs are in the .gold files.

The test files whose names end with "n" contain intentional semantic errors and are expected to fail during compilation.

Prerequisites

Platform

Recodex uses Linux and GCC to compile and run your submissions. It may trigger errors which escaped detection in other compile/run environments. For such cases, it is advantageous to have a GCC-based build environment prepared beforehand.

On the other hand, the Cecko sources are intended to be multi-platform and the skeleton is regularly tested with both GCC and Microsoft Visual C++. Therefore, development using MSVC is possible (and encouraged).

Windows Subsystem for Linux

For developers equipped with Windows 10, Windows Subsystem for Linux (WSL) is recommended as the best approach to multi-platform development. Compiling, running and debugging in the WSL-GCC environment is integrated in Visual Studio 2022 (as well as VS Code) and fully supported by Cecko projects.

Note: If you plan to build LLVM on your own (instead of downloading binaries), make sure that you use WSL 2 and that the working folder is at native Linux filesystem (i.e. not /mnt/...).

Git

Make yourself familiar with the principles of git.

In Linux, you will probably use command-line git which is present in all modern Linux distributions.

In Windows, TortoiseGit is the recommended option.

You may also try using the Git plugins in Visual Studio 2022 or VS Code; however, be aware that some advanced commands may not be available there.

To access gitlab.mff.cuni.cz, you will first need to login (using your SIS credentials) in its web interface and register your SSH keys there (if you have not done so yet).

Build tools

cmake

CMake 3.19 or newer is required. It is packaged in sufficiently new distributions of Linux (including Ubuntu 22.04 in WSL), installed by something like:

sudo apt install cmake

For Windows, cmake (and ninja) is installed with Visual Studio 2022 when C++ CMake tools for Windows is enabled in the Visual Studio Installer. C++ CMake tools for Linux is required when Visual Studio is used to build in WSL or remote Linux.

When using VS Code, cmake (as well as a C++ compiler) must be installed as an external tool.

ninja and zlib

If you use Visual Studio support for Linux, you may need to manually install ninja build system like:

sudo apt install ninja-build

In some Linux distributions, you may encounter linker complaining about -lz. The remedy is installing libz like:

sudo apt install zlib1g-dev

bison and flex

bison 3.4 and flex 2.6.4 or newer are required. They are present in any (sufficiently new) distribution of Linux (including WSL), installed by something like:

sudo apt install bison flex

For Windows, they may be downloaded from lexxmark/winflexbison. Unpack the .zip to a suitable location and add the folder to the Path variable using the Edit the system environment variables control panel dialog. This package contains win_bison.exe and win_flex.exe - these names are recognized by cmake.

If you are unable to install bison/flex into system folders or if cmake does not find (the correct version of) bison or flex, you may specify it explicitly when invoking cmake:

cmake -DBISON_ROOT=<bison_install_folder> -DFLEX_ROOT=<flex_install_folder> ...

Note that the bison executable must be located in <bison_install_folder>/bin etc.

Within Visual Studio, you may specify the BISON_ROOT and FLEX_ROOT in the CMake Settings.

Note: You may also use the winflexbison3 package from Chocolatey.

Note: You cannot use WSL installations of bison/flex for MSVC builds (and vice versa) because cmake would not invoke them properly. Therefore you will probably end with two bison/flex installations if you do both MSVC and GCC builds, similarly to having two installations of cmake in this case.

Installation using WinGet

WinGet is a package manager available by default in Windows 11. However, the WinGet package WinFlexBison.win_flex_bison is broken and can only be installed using this method:

C++20 compiler

MSVC 19.36 (part of Visual Studio 2022 v17.6) and gcc 11.4.0 are verified to be sufficient for the compilation of Cecko.

LLVM

Cecko uses the intermediate code (IR) and JIT x86 code generator (MCJIT) from the LLVM framework. The required version is LLVM 15 or newer; the tests in Recodex run with LLVM 19.1.0.

Although the LLVM team recommends building LLVM from sources, it may be well beyond the capability and patience of most Cecko developers. Therefore, downloading a binary version is recommended.

Note: Cecko requires only headers and static libraries; however, all binary distributions of LLVM include also many executables and dynamic libraries. Some downloads/packages include only the executables which is insufficient for Cecko. This also applies to some downloads at LLVM Pre-Built Binaries

Linux (including Ubuntu 22.04 in WSL) - using system-wide installation

The simplest way to install the required LLVM modules is from a Linux distribution channel, like:

sudo apt install llvm-19

cmake will automatically find LLVM if installed in this way.

Note: Although these libraries are compatible with Debug mode, they do not contain full debug info, for example, stepping into LLVM procedures during debugging of Cecko may be impossible.

Linux - installing and using private LLVM copy

Pre-built LLVM 19.1.0 binaries for Cecko are available here:

Note: These are the same binaries as used in Recodex, compiled with g++ 14.2.0

When building Cecko with a private LLVM installation, cmake must be instructed to find LLVM by setting the LLVM_DIR cmake variable to the value <llvm-install-folder>/lib/cmake/llvm as follows:

cmake -DLLVM_DIR=<llvm-install-folder>/lib/cmake/llvm <...other-arguments...>

Windows binaries

Beware: The Windows versions of Pre-Built Binaries published by LLVM (as of October 2023) are not complete enough for Cecko.

Beware: vcpkg can now install LLVM; however, the installation is implemented by building from sources and may take several hours.

Pre-built LLVM binaries for Cecko are available here:

Visual Studio CMake Configuration CMAKE_BUILD_TYPE Download
x64-Debug x64-Release
(default) (incompatible) Debug llvm-17.0.1-install-x86_64-msvc-19.36-debug.zip (1.2 GB)
(incompatible) (default) RelWithDebugInfo llvm-17.0.1-install-x86_64-msvc-19.36-relwithdebinfo.zip (651 MB)
(incompatible) (works) Release llvm-17.0.1-install-x86_64-msvc-19.36-release.zip (332 MB)

Note: The above binaries are compatible with Visual Studio 2022 v17.2.0 (May 2022) or newer.

When building Cecko, cmake must be instructed to find LLVM by setting the LLVM_DIR cmake variable to the value <llvm-install-folder>/lib/cmake/llvm.

In Visual Studio 2022, the LLVM_DIR variable is set in the CMake variables and cache section of the CMake Settings (CMakeSettings.json); you may run Generate Cache to pre-create this variable before setting it to the correct value.

In VS Code, the LLVM_DIR variable is located in the cmake.configureSettings entry of .vscode/settings.json.

When cmake is invoked from command-line, it may look like:

cmake -GNinja -DLLVM_DIR=<llvm-install-folder>/lib/cmake/llvm <...other-arguments...>	

Note: Make sure you use ninja (-GNinja) as the cmake Generator. Modern versions of cmake for Windows generate Visual Studio projects by default and some commands described in this guide do not work correctly in this mode. If cmake is invoked by Visual Studio, Ninja is enforced by default.

Note: If you compile with Microsoft Visual C++ from command-line, make sure that the x64 version of cl is visible when cmake is invoked (e.g. by starting from the "x64 Native Tools Command Prompt for VS 2022"). The cecko system is incompatible with 32-bit x86 mode which could be the default elsewhere.

Building LLVM (advanced)

If you decide to ignore binary distributions and build LLVM on your own (beware, it may require several hours of downloading and building), the simplest approach is cloning llvm-project into a <llvm-project-folder>:

git clone https://github.com/llvm/llvm-project.git <llvm-project-folder>	

If you want to have exactly the same version as in recodex, checkout the tag llvmorg-17.0.1.

To build and install, create a <llvm-build-folder> and a <llvm-install-folder>, then configure, build and install using:

cd <llvm-build-folder>
cmake -GNinja -DLLVM_PARALLEL_COMPILE_JOBS=8 -DLLVM_PARALLEL_LINK_JOBS=1 \
  -DLLVM_TARGETS_TO_BUILD=X86 -DCMAKE_BUILD_TYPE=Debug \
  -DCMAKE_INSTALL_PREFIX=<llvm-install-folder> \
  <llvm-project-folder>/llvm
cmake --build .
cmake --install .

When building Cecko with the home-built LLVM, define the LLVM_DIR variable as <llvm-install-folder>/lib/cmake/llvm.

See also Building LLVM with CMake.

The Cecko repository

To be defined.

Building and running Cecko

Building

Command-line

Create a <build-folder>, by convention as <cecko-folder>/build. Then configure using these commands:

cd <build-folder>
cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_DIR=<llvm-install-folder>/lib/cmake/llvm <cecko-folder>

The -DLLVM_DIR option is usually not required if LLVM was installed as a system package.

Building is then done by invoking cmake --build . or make in <build-folder>.

The resulting executables are located in <build-folder>/stud-main and invoked like:

cd <build-folder>
<build-folder>/stud-main/cecko1 <cecko-folder>/test/test1.c

Visual Studio 2022

Open the <cecko-folder> with Visual Studio.

When opened for the first time, use PROJECT/CMake Settings to adjust the cmake configuration, the LLVM_DIR variable in particular (see Prerequisites). The default x64-Debug configuration is created automatically; to use WSL, add the WSL-GCC-Debug configuration, adjust it if necessary and switch to it.

See also the related Visual Studio Documentation.

Visual Studio Code

In Windows, install the Visual C++ compiler first. Then start an x64 Developer Command Prompt (which defines the environment where the compiler is visible), then run code from the command prompt. Then follow the documentation for the CMake Tools extension.

Running

Command-line

The resulting executables are located in <build-folder>/stud-main and invoked like:

cd <build-folder>
<build-folder>/stud-main/cecko1 <cecko-folder>/test/test1.c

Visual Studio 2022

Open DEBUG -> Debug and Launch Settings for … (launch.vs.json) and add the following settings into the x64 configuration(s) in use:

"currentDir": ".",
"args": [ "test\\test1.c" ]

For WSL configuration(s), use:

"cwd": ".",
"args": [ "test/test1.c" ]

For remote Linux configuration(s), adjust remoteCMakeListsRoot in CMakeSettings.json so that it does not use the $HOME variable, then use:

"cwd": "${cmake.remoteCMakeListsRoot}",
"args": [ "test/test1.c" ]

Note that WSL and remote Linux use the same debug config ("type": "cppgdb"); therefore, there is probably no setting that works simultaneously in both cases.

See also the related Visual Studio Documentation.

Visual Studio Code

T.B.D.