mirror of
https://github.com/mudler/luet.git
synced 2025-09-05 17:20:29 +00:00
update vendor/
This commit is contained in:
254
vendor/github.com/crillab/gophersat/bf/parser.go
generated
vendored
Normal file
254
vendor/github.com/crillab/gophersat/bf/parser.go
generated
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
package bf
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/token"
|
||||
"io"
|
||||
"text/scanner"
|
||||
)
|
||||
|
||||
type parser struct {
|
||||
s scanner.Scanner
|
||||
eof bool // Have we reached eof yet?
|
||||
token string // Last token read
|
||||
}
|
||||
|
||||
// Parse parses the formula from the given input Reader.
|
||||
// It returns the corresponding Formula.
|
||||
// Formulas are written using the following operators (from lowest to highest priority) :
|
||||
//
|
||||
// - for a conjunction of clauses ("and"), the ";" operator
|
||||
//
|
||||
// - for an equivalence, the "=" operator,
|
||||
//
|
||||
// - for an implication, the "->" operator,
|
||||
//
|
||||
// - for a disjunction ("or"), the "|" operator,
|
||||
//
|
||||
// - for a conjunction ("and"), the "&" operator,
|
||||
//
|
||||
// - for a negation, the "^" unary operator.
|
||||
//
|
||||
// - for an exactly-one constraint, names of variables between curly braces, eg "{a, b, c}" to specify
|
||||
// exactly one of the variable a, b or c must be true.
|
||||
//
|
||||
// Parentheses can be used to group subformulas.
|
||||
// Note there are two ways to write conjunctions, one with a low priority, one with a high priority.
|
||||
// The low-priority one is useful when the user wants to describe a whole formula as a set of smaller formulas
|
||||
// that must all be true.
|
||||
func Parse(r io.Reader) (Formula, error) {
|
||||
var s scanner.Scanner
|
||||
s.Init(r)
|
||||
p := parser{s: s}
|
||||
p.scan()
|
||||
f, err := p.parseClause()
|
||||
if err != nil {
|
||||
return f, err
|
||||
}
|
||||
if !p.eof {
|
||||
return nil, fmt.Errorf("expected EOF, found %q at %v", p.token, p.s.Pos())
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func isOperator(token string) bool {
|
||||
return token == "=" || token == "->" || token == "|" || token == "&" || token == ";"
|
||||
}
|
||||
|
||||
func (p *parser) scan() {
|
||||
p.eof = p.eof || (p.s.Scan() == scanner.EOF)
|
||||
p.token = p.s.TokenText()
|
||||
}
|
||||
|
||||
func (p *parser) parseClause() (f Formula, err error) {
|
||||
if isOperator(p.token) {
|
||||
return nil, fmt.Errorf("unexpected token %q at %s", p.token, p.s.Pos())
|
||||
}
|
||||
f, err = p.parseEquiv()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if p.eof {
|
||||
return f, nil
|
||||
}
|
||||
if p.token == ";" {
|
||||
p.scan()
|
||||
if p.eof {
|
||||
return f, nil
|
||||
}
|
||||
f2, err := p.parseClause()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return And(f, f2), nil
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (p *parser) parseEquiv() (f Formula, err error) {
|
||||
if p.eof {
|
||||
return nil, fmt.Errorf("At position %v, expected expression, found EOF", p.s.Pos())
|
||||
}
|
||||
if isOperator(p.token) {
|
||||
return nil, fmt.Errorf("unexpected token %q at %s", p.token, p.s.Pos())
|
||||
}
|
||||
f, err = p.parseImplies()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if p.eof {
|
||||
return f, nil
|
||||
}
|
||||
if p.token == "=" {
|
||||
p.scan()
|
||||
if p.eof {
|
||||
return nil, fmt.Errorf("unexpected EOF")
|
||||
}
|
||||
f2, err := p.parseEquiv()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Eq(f, f2), nil
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (p *parser) parseImplies() (f Formula, err error) {
|
||||
f, err = p.parseOr()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if p.eof {
|
||||
return f, nil
|
||||
}
|
||||
if p.token == "-" {
|
||||
p.scan()
|
||||
if p.eof {
|
||||
return nil, fmt.Errorf("unexpected EOF")
|
||||
}
|
||||
if p.token != ">" {
|
||||
return nil, fmt.Errorf("invalid token %q at %v", "-"+p.token, p.s.Pos())
|
||||
}
|
||||
p.scan()
|
||||
if p.eof {
|
||||
return nil, fmt.Errorf("unexpected EOF")
|
||||
}
|
||||
f2, err := p.parseImplies()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Implies(f, f2), nil
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (p *parser) parseOr() (f Formula, err error) {
|
||||
f, err = p.parseAnd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if p.eof {
|
||||
return f, nil
|
||||
}
|
||||
if p.token == "|" {
|
||||
p.scan()
|
||||
if p.eof {
|
||||
return nil, fmt.Errorf("unexpected EOF")
|
||||
}
|
||||
f2, err := p.parseOr()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Or(f, f2), nil
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (p *parser) parseAnd() (f Formula, err error) {
|
||||
f, err = p.parseNot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if p.eof {
|
||||
return f, nil
|
||||
}
|
||||
if p.token == "&" {
|
||||
p.scan()
|
||||
if p.eof {
|
||||
return nil, fmt.Errorf("unexpected EOF")
|
||||
}
|
||||
f2, err := p.parseAnd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return And(f, f2), nil
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (p *parser) parseNot() (f Formula, err error) {
|
||||
if isOperator(p.token) {
|
||||
return nil, fmt.Errorf("unexpected token %q at %s", p.token, p.s.Pos())
|
||||
}
|
||||
if p.token == "^" {
|
||||
p.scan()
|
||||
if p.eof {
|
||||
return nil, fmt.Errorf("unexpected EOF")
|
||||
}
|
||||
f, err = p.parseNot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Not(f), nil
|
||||
}
|
||||
f, err = p.parseBasic()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (p *parser) parseBasic() (f Formula, err error) {
|
||||
if isOperator(p.token) || p.token == ")" {
|
||||
return nil, fmt.Errorf("unexpected token %q at %s", p.token, p.s.Pos())
|
||||
}
|
||||
if p.token == "(" {
|
||||
p.scan()
|
||||
f, err = p.parseEquiv()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if p.eof {
|
||||
return nil, fmt.Errorf("expected closing parenthesis, found EOF at %s", p.s.Pos())
|
||||
}
|
||||
if p.token != ")" {
|
||||
return nil, fmt.Errorf("expected closing parenthesis, found %q at %s", p.token, p.s.Pos())
|
||||
}
|
||||
p.scan()
|
||||
return f, nil
|
||||
}
|
||||
if p.token == "{" {
|
||||
var vars []string
|
||||
for p.token != "}" {
|
||||
p.scan()
|
||||
if p.eof {
|
||||
return nil, fmt.Errorf("expected identifier, found EOF at %s", p.s.Pos())
|
||||
}
|
||||
if token.Lookup(p.token) != token.IDENT {
|
||||
return nil, fmt.Errorf("expected variable name, found %q at %s", p.token, p.s.Pos())
|
||||
}
|
||||
vars = append(vars, p.token)
|
||||
p.scan()
|
||||
if p.eof {
|
||||
return nil, fmt.Errorf("expected comma or closing brace, found EOF at %s", p.s.Pos())
|
||||
}
|
||||
if p.token != "}" && p.token != "," {
|
||||
return nil, fmt.Errorf("expected comma or closing brace, found %q at %v", p.token, p.s.Pos())
|
||||
}
|
||||
}
|
||||
p.scan()
|
||||
return Unique(vars...), nil
|
||||
}
|
||||
defer p.scan()
|
||||
return Var(p.token), nil
|
||||
}
|
Reference in New Issue
Block a user