Macro PEG extends Parsing Expression Grammars with macro-like rules and is implemented in Scala 3. It supports lambda-style macros so you can build higher-order grammars.
Whitespace is omitted in the grammar below.
Grammar <- Definition* ";"
Definition <- Identifier ("(" Arg ("," Arg)* ")")? "=" Expression ";"
Arg <- Identifier (":" Type)?
Type <- RuleType / "?"
RuleType <- ("(" Type ("," Type)* ")" "->" Type)
/ (Type "->" Type)
Expression <- Sequence ("/" Sequence)*
Sequence <- Prefix+
Prefix <- ("&" / "!") Suffix
/ Suffix
Suffix <- Primary "?"
/ Primary "*"
/ Primary "+"
/ Primary
Primary <- "(" Expression ")"
/ Call
/ Debug
/ Identifier
/ StringLiteral
/ CharacterClass
/ Lambda
Call <- Identifier "(" Expression ("," Expression)* ")"
Debug <- "Debug" "(" Expression ")"
Lambda <- "(" Identifier ("," Identifier)* "->" Expression ")"
StringLiteral <- '"' (!'"' .)* '"'
CharacterClass<- '[' '^'? (!']' .)+ ']'
- Macro rules with parameters
- Lambda macros for higher-order grammars
- Type annotations for macro parameters
- Multiple evaluation strategies (call by name, call by value sequential/parallel)
- Parser combinator library
MacroParsers
- Debug expressions for inspecting matches
Add the library to your build.sbt
:
libraryDependencies += "com.github.kmizu" %% "macro_peg" % "0.1.1-SNAPSHOT"
Then parse and evaluate a grammar:
import com.github.kmizu.macro_peg._
val grammar = Parser.parse("""
S = Double((x -> x x), "aa") !.;
Double(f: ?, s: ?) = f(f(s));
""")
val evaluator = Evaluator(grammar)
val result = evaluator.evaluate("aaaaaaaa", Symbol("S"))
println(result)
- Introduce backreference as
evalCC
method. - pfun -> delayedParser, which is better naming than before(breaking change)
- More accurate ParseException
- EvaluationException is thrown when arity of function is not equal to passed params.
- Improved Parser
Execute the following command:
sbt test
This project is released under the MIT License.