When I studied compiler theory, a large part of the compilation involved a lexical analyser (e.g. `flex`) and a syntax analyser (e.g. `bison`), that would produce an internal representation of the input code (the AST), used to generate the compiled files.
It seems that the terminology as evolved, as we speak more broadly of frontends and backends.
So, I'm wondering if Bison and Flex (or equivalent tools) are still in use by the modern compilers? Or are they built directly in GCC, LLVM, ...?
The other answers are great, but let me just add that C++ cannot be parsed with conventional LL/LALR/LR parsers, because the syntax is ambiguous and requires disambiguation via type checking (i.e., there may be multiple parse trees but at most one will type check).
There was some research on parsing C++ with GLR but I don't think it ever made it into production compilers.
Other, more sane languages with unambiguous grammars may still choose to hand-write their parsers for all the reasons mentioned in the sibling comments. However, I would note that, even when using a parsing library, almost every compiler in existence will use its own AST, and not reuse the parse tree generated by the parser library. That's something you would only ever do in a compiler class.
Also I wouldn't say that frontend/backend is an evolution of previous terminology, it's just that parsing is not considered an "interesting" problem by most of the community so the focus has moved elsewhere (from the AST design through optimization and code generation).
Note that depending on what parsing lib you use, it may produce nodes of your own custom AST type
Personally I love the (Rust) combo of logos for lexing, chumsky for parsing, and ariadne for error reporting. Chumsky has options for error recovery and good performance, ariadne is gorgeous (there is another alternative for Rust, miette, both are good).
The only thing chumsky is lacking is incremental parsing. There is a chumsky-inspired library for incremental parsing called incpa though
If you want something more conservative for error reporting, annotate-snippets is finally at parity with rustc's current custom renderer and will soon become the default for both rustc and cargo.
GLR C++ parsers were for a short time in use on production code at Mozilla, in refactoring tools: Oink (and it's fork, pork). Not quite sure what ended that, but I don't think it was any issue with parsing.
"Frontend" as used by mainstream compilers is slightly broader than just lexing/parsing.
In typical modern compilers "frontend" is basically everything involving analyzing the source language and producing a compiler-internal IR, so lexing, parsing, semantic analysis and type checking, etc. And "backend" means everything involving producing machine code from the IR, so optimization and instruction selection.
In the context of Rust, rustc is the frontend (and it is already a very big and complicated Rust program, much more complicated than just a Rust lexer/parser would be), and then LLVM (typically bundled with rustc though some distros package them separately) is the backend (and is another very big and complicated C++ program).
Table-driven parsers with custom per-statement tokenizers are still common in surviving Fortran compilers, with the exception of flang-new in LLVM. I used a custom parser combinator library there, inspired by a prototype in Haskell's Parsec, to implement a recursive descent algorithm with backtracking on failure. I'm still happy with the results, especially with the fact that it's all very strongly typed and coupled with the parse tree definition.
Not sure about GCC, but in general there has been a big move away from using parser generators like flex/bison/ANTLR/etc, and towards using handwritten recursive descent parsers. Clang (which is the C/C++ frontend for LLVM) does this, and so does rustc.
This was in the olden days when your language's type system would maybe look like C's if you were serious and be even less of a thing when you were not.
The hard part about compiling Rust is not really parsing, it's the type system including parts like borrow checking, generics, trait solving (which is turing-complete itself), name resolution, drop checking, and of course all of these features interact in fun and often surprising ways. Also macros. Also all the "magic" types in the StdLib that require special compiler support.
This is why e.g. `rustc` has several different intermediate representations. You no longer have "the" AST, you have token trees, HIR, THIR, and MIR, and then that's lowered to LLVM or Cranelift or libgccjit. Each stage has important parts of the type system happen.
Most roll their own for three reasons: performance, context, and error handling. Bison/Menhir et al. are easy to write a grammar and get started with, but in exchange you get less flexibility overall. It becomes difficult to handle context-sensitive parts, do error recovery, and give the user meaningful errors that describe exactly what’s wrong. Usually if there’s a small syntax error we want to try to tell the user how to fix it instead of just producing “Syntax error”, and that requires being able to fix the input and keep parsing.
Menhir has a new mode where the parser is driven externally; this allows your code to drive the entire thing, which requires a lot more machinery than fire-and-forget but also affords you more flexibility.
If you're parsing a new language that you're trying to define, I do recommend using a parser generator to check your grammar, even if your "real" parser is handwritten for good reasons. A parser generator will insist on your grammar being unambiguous, or at least tell you where it is ambiguous. Without this sanity check, your unconstrained handwritten parser is almost guaranteed to not actually parse the language you think it parses.
That is also my feeling, at least from a part of the GrapheneOS community. I have seen them despising and bullying /e/OS, Debian, F-Droid, the Linux kernel... Too bad for this project, that is amazing, to have such toxic folks.
Open source communities should help each other, and work together, not fight.
You can't equate actions from a part of the community with actions by the project. If you would see any bigotry by a GrapheneOS community member, please report it to the moderators. Bullying, toxcity and misinfo are not allowed. Action will be taken.
I havent noticed a lot of that in the community myself, in which im very active. Its exceptional in my eyes. Common though is technical criticism on other projects when people ask advice about it or want a comparison with alternative. Also common is people being fed up by harassment by other projects.
The founder of /e/OS repeatdely attacks GrapheneOS in random internet threads that are only mention GrapheneOS. This contrast with the approach of GrapheneOS where they will only do a comparison with /e/OS in reponse to posts where both are mentioned and compared by others. Or, in reponse of wrong comparisons in the media or harassment (personal attacks etc.) stemming from them.
F-Droid does also have some maintainers that engaged in personal attacks against the GOS founder. And anyway what do you expect the project to do if people ask whether to get apps from Play Store or F-Droid? Pretend there is no technical security difference? If people ask questions, the project and community try to inform.
There is big conflict with Debian or Linux kernel at all. They also dont mismarket themselves or spread misinfo about GrapheneOS. They are concerned though that both heavily used projects lack a security focus.
If only UX/UI people spent their time optimizing their code rather than polishing their animations.
Sorry for this rant, but hell, the web, the apps, everything is so sloooow and bloated. Make it instant! I just want to do my things, not to wait for drawings to draw!
Not really, despite the repo being named MentraOS, this repo seems to include only some mobile apps (that either run on a phone or on the glasses), some server code, and some SDKs.
Mentra glasses are likely running on a fork of AOSP, which is not in this repo.
Mentra Live runs AOSP similar to the other AI glasses on the market (Ray-Ban, Xiaomi AI Glasses, RayNeo V3 AI Glasses, etc). It's heavy, but allows us to ship fast. You'll find this code in `asg_client` folder.
We're also working on a pair of HUD glasses that will release in 2026 using an NRF5340 MCU. The code for this is being developed in the `mcu_client` folder.
Please have an option for local processing. I would love to be able to use my locally running Gemma 3n model on my phone for low latency and for them to work without internet connectivity.
We're going to be putting out a Mentra Edge SDK in the next few months, but it comes with some downsides. Using your phone as a compute device is a battery hog, and you can only connect one app to the glasses at a time.
>> AOSP (or even a minimal fork) is way too heavy to be running on the glasses
> Meta Horizon OS, previously known informally as Meta Quest Platform or Meta Quest OS, is an Android-based extended reality operating system for the Meta Quest line of devices released by Meta Platforms.
Most smart glasses just run AOSP, that's the path of least resistance. Ones without displays are often just Bluetooth headsets in shape of eyeglasses, and only the ones with cameras but not displays are the ones that run a lightweight OS.
Right, most probably closed-source just like Android wear. Even manufacturers may not have access to the source code, they would just put their stuff in the vendor partition.
A good friend of mine works for a manufacturer that make watches running on Android Wear, and closed-source system updates pushed by Google turn OS-level regressions (like battery consumption issues) into nightmares. So they are switching back to their own AOSP-based OS.
It seems that the terminology as evolved, as we speak more broadly of frontends and backends.
So, I'm wondering if Bison and Flex (or equivalent tools) are still in use by the modern compilers? Or are they built directly in GCC, LLVM, ...?