Skip to content

leissa/fe

Repository files navigation

FE

Linux Windows macOS Doxygen License: MIT

[TOC]

FE is a header-only C++20 toolkit for building handwritten compiler and interpreter frontends.

Rather than generating lexers or parsers for you, FE focuses on the infrastructure that every frontend needs anyway: source locations, diagnostics, interning, parsing support, and efficient memory management. The goal is simple: keep handwritten frontends lightweight, explicit, and pleasant to maintain.

💡 Why FE?

FE is a good fit if you want to build:

  • a small programming language or DSL,
  • a hand-written recursive-descent parser,
  • a lexer with precise UTF-8-aware source tracking,
  • a frontend with high-quality diagnostics,
  • a prototype compiler or interpreter that should stay easy to evolve.

It is especially useful when you want the flexibility of handwritten code without repeatedly rebuilding the same frontend infrastructure from scratch.

✨ Features

Handwritten frontends are often the right choice when you want full control over syntax, diagnostics, recovery, and architecture. FE embraces that style.

It provides a compact set of reusable, well-integrated components:

  • fe::Arena for fast arena allocation and arena-backed ownership.
  • fe::Sym and fe::SymPool for string interning and cheap identifier comparison.
  • fe::Driver for diagnostics and shared frontend state.
  • fe::Pos and fe::Loc for source positions and source spans.
  • fe::Lexer<K, S> for UTF-8-aware lexing with lookahead and token text accumulation.
  • fe::Parser<Tok, Tag, K, S> for recursive-descent-style parsing with token lookahead and span tracking.
  • Optional FE_ABSL support for Abseil hash containers.

FE does not try to hide frontend construction behind a generator. Instead, it gives you sharp, reusable tools so you can build exactly the frontend you want.

For a complete end-to-end example, see Let, a small toy language built on FE..

🚀 Quick Start

The easiest way to get going is through Let.

You can either:

That gives you a concrete, working example of how FE is intended to be used in practice.

Integrate into existing Project

CMake

Add FE as a subdirectory and link the fe interface target:

add_subdirectory(external/fe)
target_link_libraries(my_compiler PRIVATE fe)

If you want Abseil-backed hash containers, enable FE_ABSL before adding the subdirectory:

set(FE_ABSL ON)
add_subdirectory(external/fe)
target_link_libraries(my_compiler PRIVATE fe)

Direct Vendoring

Because FE is header-only, you can also vendor include/fe/ directly into your project.

If you want Abseil support in that setup, compile with:

-DFE_ABSL

🧭 Typical Workflow

A typical FE-based frontend looks roughly like this:

  1. Define a token type exposing tag() and loc().
  2. Implement your lexer by deriving from fe::Lexer<K, S>.
  3. Implement your parser by deriving from fe::Parser<Tok, Tag, K, S>.
  4. Use fe::Driver to centralize diagnostics and shared state.
  5. Thread fe::Loc through tokens and AST nodes for precise error reporting.
  6. Use fe::Arena and symbol interning where allocation cost and identifier handling matter.

If you want a concrete model to copy from, start with tests/lexer.cpp.

🛠️ Building and Testing

To configure, build, and run the test suite:

cmake -S . -B build -DBUILD_TESTING=ON
cmake --build build
ctest --test-dir build --output-on-failure

To run one discovered test:

ctest --test-dir build -R '^Lexer$' --output-on-failure

To run a doctest case directly:

./build/bin/fe-test --test-case=Lexer

📚 Building the Documentation

To build the documentation:

cmake -S . -B build -DFE_BUILD_DOCS=ON
cmake --build build --target docs

This requires Doxygen and Graphviz (dot).

🔨 Related Projects

A few projects that use or reflect the same frontend philosophy:

  • Let - a small demo language built on FE.
  • MimIR - an intermediate representation project by the author.
  • GraphTool - a DOT-language tool using FE-style frontend infrastructure.
  • SQL - a small SQL parser.

⚖️ License

FE is licensed under the MIT License.

About

A header-only C++ library for writing compiler/interpreter frontends.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors