File: main.go

package info (click to toggle)
golang-github-alecthomas-participle-v2 2.1.4-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 920 kB
  • sloc: javascript: 1,164; sh: 41; makefile: 7
file content (85 lines) | stat: -rw-r--r-- 2,104 bytes parent folder | download
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)
}