https://github.com/nateseymour/buffalo
C++23 Parser Generator
https://github.com/nateseymour/buffalo
bison cplusplus cplusplus-23 parser-generator
Last synced: 3 months ago
JSON representation
C++23 Parser Generator
- Host: GitHub
- URL: https://github.com/nateseymour/buffalo
- Owner: NateSeymour
- License: mit
- Created: 2024-08-02T18:15:38.000Z (almost 2 years ago)
- Default Branch: master
- Last Pushed: 2025-05-04T17:12:49.000Z (about 1 year ago)
- Last Synced: 2025-05-04T18:21:11.574Z (about 1 year ago)
- Topics: bison, cplusplus, cplusplus-23, parser-generator
- Language: C++
- Homepage: https://nateseymour.github.io/buffalo/
- Size: 401 KB
- Stars: 4
- Watchers: 1
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# buffalo
> *buffalo: to bewilder, baffle (also: **bamboozle**)* [2024 Merriam-Webster Dictionary]
Bewilder, baffle (even bamboozle!) your grammars with `buffalo`, a C++23 header-only SLR parser generator with
`yacc/bison`-like syntax.
It supports the definition of terminals, non-terminals and grammar structures all within the same C++ file.
## Features
- Terminal definition with builtin scanning based on `compile-time-regular-expressions` (`spex`).
- Grammar definition in pseudo BNF notation.
- Shift/Reduce conflict resolution through precedence (based on definition order) and associativity (left/right/none).
## Compiler Support
`buffalo` officially supports the following compilers:
- GCC 14
- Clang 18
- MSVC
## Examples
### Calculator
```c++
/* calculator.cpp */
#include
#include
/*
* Grammar Definition
*/
using G = bf::GrammarDefinition;
/*
* Terminals
*/
bf::DefineTerminal NUMBER([](auto const &tok) {
return std::stod(std::string(tok.raw));
});
bf::DefineTerminal OP_EXP(bf::Right);
bf::DefineTerminal OP_MUL(bf::Left);
bf::DefineTerminal OP_DIV(bf::Left);
bf::DefineTerminal OP_ADD(bf::Left);
bf::DefineTerminal OP_SUB(bf::Left);
bf::DefineTerminal PAR_OPEN;
bf::DefineTerminal PAR_CLOSE;
/*
* Non-Terminals
*/
bf::DefineNonTerminal expression
= bf::PR(NUMBER)<=>[](auto &$) { return $[0]; }
| (PAR_OPEN + expression + PAR_CLOSE)<=>[](auto &$) { return $[1]; }
| (expression + OP_EXP + expression)<=>[](auto &$) { return std::pow($[0], $[2]); }
| (expression + OP_MUL + expression)<=>[](auto &$) { return $[0] * $[2]; }
| (expression + OP_DIV + expression)<=>[](auto &$) { return $[0] / $[2]; }
| (expression + OP_ADD + expression)<=>[](auto &$) { return $[0] + $[2]; }
| (expression + OP_SUB + expression)<=>[](auto &$) { return $[0] - $[2]; }
;
bf::DefineNonTerminal statement
= bf::PR(expression)<=>[](auto &$)
{
return $[0];
}
;
/*
* Calculations
*/
auto calculator = bf::SLRParser::Build(statement);
double result = *calculator.Parse("18 + 2^(1 + 1) * 4");
```