modulepackage
0.1.0
Repository: https://github.com/vovan-ve/go-lr0-parser.git
Documentation: pkg.go.dev
# 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.
Theory
License
# Packages
No description provided by the author
# Functions
New creates new Parser
terminals can be defined with NewTerm or NewWhitespace
rules can be defined by NewNT
parser := New( []Terminal{ NewTerm(tInt, "int").FuncByte(isDigit, bytesToInt), NewTerm(tPlus, `"+"`).Hide().Str("+"), NewWhitespace().FuncRune(unicode.IsSpace), }, []NonTerminalDefinition{ NewNT(nGoal, "Goal").Main().Is(nSum), NewNT(nSum, "Sum").
NewNT created new non-terminal definition
NewNT(nGoal, "Goal").Main().
NewParseError creates new Error by wrapping ErrParse.
NewState creates new State for the given buffer `input` pointing to its start.
NewTerm starts new Terminal creation.
NewWhitespace can be used to define internal terminals to skip whitespaces
Can be used multiple times to define different kinds of whitespaces.
WithSource wraps the given error to append State info to error message.
# Constants
InvalidId id zero value for Id.
# Variables
ErrConflictReduceReduce means that there are a number of rules which applicable to reduce in the current state.
ErrConflictShiftReduce means that Shift and Reduce are both applicable in the current state.
ErrDefine will be raised by panic in case of invalid definition.
ErrInternal is an internal error which actually should not be raised, but coded in some panic for debug purpose just in case.
ErrNegativeOffset will be raised by panic if some operation with State cause negative offset ErrNegativeOffset will be raised by panic if some operation with State cause negative offset.
ErrParse is base error for run-time errors about parsing.
ErrState is base wrap error for parsing state.
# Structs
Match is a found Terminal representation.
NonTerminal is NonTerminalDefinition implementation with chainable definition API.
State describes an immutable state of reading the underlying buffer at the given position.
TerminalFactory is a helper API to define a Terminal.
# Interfaces
No description provided by the author
NonTerminalDefinition is an interface to make Rules for non-terminal.
Parser is object preconfigured for a specific grammar, ready to parse an input to evaluate the result.
Rule is one of possible definition for a non-Terminal.
No description provided by the author
Symbol is common interface to describe Symbol meta data.
No description provided by the author
Terminal is interface to parse specific type of token from input State.