repositorypackage
0.1.0
Repository: https://github.com/vovan-ve/go-lr0-parser.git
Documentation: pkg.go.dev
# Packages
No description provided by the author
# README
LR(0) Parser
This package contains LR(0) parser to parse text according to defined LR(0) grammar.
It's based on my previous PHP library, but with some package API enhancements.
Example
package main
import (
"fmt"
"log"
"os"
"strconv"
"github.com/vovan-ve/go-lr0-parser"
)
const (
tInt lr0.Id = iota + 1
tPlus
tMinus
nVal
nSum
nGoal
)
var parser = lr0.New(
[]lr0.Terminal{
lr0.NewTerm(tInt, "int").FuncByte(isDigit, bytesToInt),
lr0.NewTerm(tPlus, `"+"`).Hide().Str("+"),
lr0.NewTerm(tMinus, `"-"`).Hide().Str("-"),
},
[]lr0.NonTerminalDefinition{
lr0.NewNT(nGoal, "Goal").Main().Is(nSum),
lr0.NewNT(nSum, "Sum").
Is(nSum, tPlus, nVal).Do(func(a, b int) int { return a + b }).
Is(nSum, tMinus, nVal).Do(func(a, b int) int { return a - b }).
Is(nVal),
lr0.NewNT(nVal, "Val").Is(tInt),
},
)
func main() {
if len(os.Args) <= 1 {
log.Println("no args to calc")
return
}
for i, input := range os.Args[1:] {
fmt.Printf("%d> %s\t=> ", i, input)
result, err := parser.Parse(lr0.NewState([]byte(input)))
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println(result)
}
}
}
func isDigit(b byte) bool { return b >= '0' && b <= '9' }
func bytesToInt(b []byte) (int, error) { return strconv.Atoi(string(b)) }
$ go build -o calc examples/01-calc-tiny/main.go
...
$ ./calc "3+8-5" "3+ 8-5" "3+8*5"
0> 3+8-5 => 6
1> 3+ 8-5 => Error: unexpected input: expected int: parse error near ⟪3+⟫⏵⟪␠8-5⟫
2> 3+8*5 => Error: unexpected input: expected "+" or "-": parse error near ⟪3+8⟫⏵⟪*5⟫
See examples in examples/ and tests.