1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
package main
import (
"strings"
"github.com/alecthomas/kong"
"github.com/alecthomas/repr"
"github.com/alecthomas/participle/v2"
)
// Based on http://www.craftinginterpreters.com/parsing-expressions.html
// expression → equality ;
// equality → comparison ( ( "!=" | "==" ) comparison )* ;
// comparison → addition ( ( ">" | ">=" | "<" | "<=" ) addition )* ;
// addition → multiplication ( ( "-" | "+" ) multiplication )* ;
// multiplication → unary ( ( "/" | "*" ) unary )* ;
// unary → ( "!" | "-" ) unary
// | primary ;
// primary → NUMBER | STRING | "false" | "true" | "nil"
// | "(" expression ")" ;
type Expression struct {
Equality *Equality `@@`
}
type Equality struct {
Comparison *Comparison `@@`
Op string `( @( "!" "=" | "=" "=" )`
Next *Equality ` @@ )*`
}
type Comparison struct {
Addition *Addition `@@`
Op string `( @( ">" | ">" "=" | "<" | "<" "=" )`
Next *Comparison ` @@ )*`
}
type Addition struct {
Multiplication *Multiplication `@@`
Op string `( @( "-" | "+" )`
Next *Addition ` @@ )*`
}
type Multiplication struct {
Unary *Unary `@@`
Op string `( @( "/" | "*" )`
Next *Multiplication ` @@ )*`
}
type Unary struct {
Op string ` ( @( "!" | "-" )`
Unary *Unary ` @@ )`
Primary *Primary `| @@`
}
type Primary struct {
Number *float64 ` @Float | @Int`
String *string `| @String`
Bool *Boolean `| @( "true" | "false" )`
Nil bool `| @"nil"`
SubExpression *Expression `| "(" @@ ")" `
}
type Boolean bool
func (b *Boolean) Capture(values []string) error {
*b = values[0] == "true"
return nil
}
var parser = participle.MustBuild[Expression](participle.UseLookahead(2))
func main() {
var cli struct {
Expr []string `arg required help:"Expression to parse."`
}
ctx := kong.Parse(&cli)
expr, err := parser.ParseString("", strings.Join(cli.Expr, " "))
ctx.FatalIfErrorf(err)
repr.Println(expr)
}
|