Commit 22f216c5 authored by Nadim Kobeissi's avatar Nadim Kobeissi
Browse files

Update libpigeon

parent ee65b9ff
// Code generated by pigeon; DO NOT EDIT.
/* SPDX-FileCopyrightText: © 2019-2021 Nadim Kobeissi <nadim@symbolic.software>
* SPDX-License-Identifier: GPL-3.0-only */
......@@ -12,10 +14,13 @@ import (
"fmt"
"io"
"io/ioutil"
"math"
"os"
"path/filepath"
"sort"
"strconv"
"strings"
"sync"
"unicode"
"unicode/utf8"
)
......@@ -164,6 +169,7 @@ var g = &grammar{
pos: position{line: 101, col: 13, offset: 2412},
val: "attacker",
ignoreCase: false,
want: "\"attacker\"",
},
&ruleRefExpr{
pos: position{line: 101, col: 24, offset: 2423},
......@@ -173,6 +179,7 @@ var g = &grammar{
pos: position{line: 101, col: 26, offset: 2425},
val: "[",
ignoreCase: false,
want: "\"[\"",
},
&ruleRefExpr{
pos: position{line: 101, col: 30, offset: 2429},
......@@ -197,6 +204,7 @@ var g = &grammar{
pos: position{line: 101, col: 53, offset: 2452},
val: "]",
ignoreCase: false,
want: "\"]\"",
},
&ruleRefExpr{
pos: position{line: 101, col: 57, offset: 2456},
......@@ -219,11 +227,13 @@ var g = &grammar{
pos: position{line: 108, col: 18, offset: 2597},
val: "active",
ignoreCase: false,
want: "\"active\"",
},
&litMatcher{
pos: position{line: 108, col: 27, offset: 2606},
val: "passive",
ignoreCase: false,
want: "\"passive\"",
},
},
},
......@@ -294,6 +304,7 @@ var g = &grammar{
pos: position{line: 116, col: 14, offset: 2748},
val: "principal",
ignoreCase: false,
want: "\"principal\"",
},
&ruleRefExpr{
pos: position{line: 116, col: 26, offset: 2760},
......@@ -315,6 +326,7 @@ var g = &grammar{
pos: position{line: 116, col: 49, offset: 2783},
val: "[",
ignoreCase: false,
want: "\"[\"",
},
&ruleRefExpr{
pos: position{line: 116, col: 53, offset: 2787},
......@@ -353,6 +365,7 @@ var g = &grammar{
pos: position{line: 116, col: 101, offset: 2835},
val: "]",
ignoreCase: false,
want: "\"]\"",
},
&ruleRefExpr{
pos: position{line: 116, col: 105, offset: 2839},
......@@ -391,16 +404,19 @@ var g = &grammar{
pos: position{line: 136, col: 15, offset: 3273},
val: "private",
ignoreCase: false,
want: "\"private\"",
},
&litMatcher{
pos: position{line: 136, col: 25, offset: 3283},
val: "public",
ignoreCase: false,
want: "\"public\"",
},
&litMatcher{
pos: position{line: 136, col: 34, offset: 3292},
val: "password",
ignoreCase: false,
want: "\"password\"",
},
},
},
......@@ -434,6 +450,7 @@ var g = &grammar{
pos: position{line: 147, col: 36, offset: 3515},
val: "->",
ignoreCase: false,
want: "\"->\"",
},
&ruleRefExpr{
pos: position{line: 147, col: 41, offset: 3520},
......@@ -458,6 +475,7 @@ var g = &grammar{
pos: position{line: 147, col: 70, offset: 3549},
val: ":",
ignoreCase: false,
want: "\":\"",
},
&ruleRefExpr{
pos: position{line: 147, col: 74, offset: 3553},
......@@ -575,6 +593,7 @@ var g = &grammar{
pos: position{line: 182, col: 10, offset: 4465},
val: "knows",
ignoreCase: false,
want: "\"knows\"",
},
&ruleRefExpr{
pos: position{line: 182, col: 18, offset: 4473},
......@@ -623,6 +642,7 @@ var g = &grammar{
pos: position{line: 196, col: 14, offset: 4873},
val: "generates",
ignoreCase: false,
want: "\"generates\"",
},
&ruleRefExpr{
pos: position{line: 196, col: 26, offset: 4885},
......@@ -656,6 +676,7 @@ var g = &grammar{
pos: position{line: 207, col: 10, offset: 5151},
val: "leaks",
ignoreCase: false,
want: "\"leaks\"",
},
&ruleRefExpr{
pos: position{line: 207, col: 18, offset: 5159},
......@@ -704,6 +725,7 @@ var g = &grammar{
pos: position{line: 218, col: 33, offset: 5440},
val: "=",
ignoreCase: false,
want: "\"=\"",
},
&ruleRefExpr{
pos: position{line: 218, col: 37, offset: 5444},
......@@ -754,6 +776,7 @@ var g = &grammar{
pos: position{line: 234, col: 33, offset: 5833},
val: ",",
ignoreCase: false,
want: "\",\"",
},
&ruleRefExpr{
pos: position{line: 234, col: 37, offset: 5837},
......@@ -798,6 +821,7 @@ var g = &grammar{
pos: position{line: 265, col: 10, offset: 6420},
val: "phase",
ignoreCase: false,
want: "\"phase\"",
},
&ruleRefExpr{
pos: position{line: 265, col: 18, offset: 6428},
......@@ -807,6 +831,7 @@ var g = &grammar{
pos: position{line: 265, col: 20, offset: 6430},
val: "[",
ignoreCase: false,
want: "\"[\"",
},
&ruleRefExpr{
pos: position{line: 265, col: 24, offset: 6434},
......@@ -834,6 +859,7 @@ var g = &grammar{
pos: position{line: 265, col: 42, offset: 6452},
val: "]",
ignoreCase: false,
want: "\"]\"",
},
&ruleRefExpr{
pos: position{line: 265, col: 46, offset: 6456},
......@@ -856,6 +882,7 @@ var g = &grammar{
pos: position{line: 278, col: 20, offset: 6697},
val: "[",
ignoreCase: false,
want: "\"[\"",
},
&labeledExpr{
pos: position{line: 278, col: 24, offset: 6701},
......@@ -869,6 +896,7 @@ var g = &grammar{
pos: position{line: 278, col: 41, offset: 6718},
val: "]",
ignoreCase: false,
want: "\"]\"",
},
&zeroOrOneExpr{
pos: position{line: 278, col: 45, offset: 6722},
......@@ -883,6 +911,7 @@ var g = &grammar{
pos: position{line: 278, col: 48, offset: 6725},
val: ",",
ignoreCase: false,
want: "\",\"",
},
&ruleRefExpr{
pos: position{line: 278, col: 52, offset: 6729},
......@@ -916,6 +945,7 @@ var g = &grammar{
pos: position{line: 291, col: 33, offset: 7003},
val: "(",
ignoreCase: false,
want: "\"(\"",
},
&ruleRefExpr{
pos: position{line: 291, col: 37, offset: 7007},
......@@ -940,6 +970,7 @@ var g = &grammar{
pos: position{line: 291, col: 58, offset: 7028},
val: ")",
ignoreCase: false,
want: "\")\"",
},
&labeledExpr{
pos: position{line: 291, col: 62, offset: 7032},
......@@ -950,6 +981,7 @@ var g = &grammar{
pos: position{line: 291, col: 68, offset: 7038},
val: "?",
ignoreCase: false,
want: "\"?\"",
},
},
},
......@@ -966,6 +998,7 @@ var g = &grammar{
pos: position{line: 291, col: 76, offset: 7046},
val: ",",
ignoreCase: false,
want: "\",\"",
},
&ruleRefExpr{
pos: position{line: 291, col: 80, offset: 7050},
......@@ -1022,6 +1055,7 @@ var g = &grammar{
pos: position{line: 312, col: 31, offset: 7477},
val: "^",
ignoreCase: false,
want: "\"^\"",
},
&ruleRefExpr{
pos: position{line: 312, col: 35, offset: 7481},
......@@ -1075,6 +1109,7 @@ var g = &grammar{
pos: position{line: 326, col: 12, offset: 7697},
val: "queries",
ignoreCase: false,
want: "\"queries\"",
},
&ruleRefExpr{
pos: position{line: 326, col: 22, offset: 7707},
......@@ -1084,6 +1119,7 @@ var g = &grammar{
pos: position{line: 326, col: 24, offset: 7709},
val: "[",
ignoreCase: false,
want: "\"[\"",
},
&ruleRefExpr{
pos: position{line: 326, col: 28, offset: 7713},
......@@ -1104,6 +1140,7 @@ var g = &grammar{
pos: position{line: 326, col: 47, offset: 7732},
val: "]",
ignoreCase: false,
want: "\"]\"",
},
&ruleRefExpr{
pos: position{line: 326, col: 51, offset: 7736},
......@@ -1178,6 +1215,7 @@ var g = &grammar{
pos: position{line: 334, col: 25, offset: 7922},
val: "confidentiality?",
ignoreCase: false,
want: "\"confidentiality?\"",
},
&ruleRefExpr{
pos: position{line: 334, col: 44, offset: 7941},
......@@ -1230,6 +1268,7 @@ var g = &grammar{
pos: position{line: 349, col: 24, offset: 8346},
val: "authentication?",
ignoreCase: false,
want: "\"authentication?\"",
},
&ruleRefExpr{
pos: position{line: 349, col: 42, offset: 8364},
......@@ -1282,6 +1321,7 @@ var g = &grammar{
pos: position{line: 364, col: 19, offset: 8749},
val: "freshness?",
ignoreCase: false,
want: "\"freshness?\"",
},
&ruleRefExpr{
pos: position{line: 364, col: 32, offset: 8762},
......@@ -1334,6 +1374,7 @@ var g = &grammar{
pos: position{line: 379, col: 23, offset: 9154},
val: "unlinkability?",
ignoreCase: false,
want: "\"unlinkability?\"",
},
&ruleRefExpr{
pos: position{line: 379, col: 40, offset: 9171},
......@@ -1386,6 +1427,7 @@ var g = &grammar{
pos: position{line: 394, col: 17, offset: 9545},
val: "[",
ignoreCase: false,
want: "\"[\"",
},
&ruleRefExpr{
pos: position{line: 394, col: 21, offset: 9549},
......@@ -1406,6 +1448,7 @@ var g = &grammar{
pos: position{line: 394, col: 46, offset: 9574},
val: "]",
ignoreCase: false,
want: "\"]\"",
},
&ruleRefExpr{
pos: position{line: 394, col: 50, offset: 9578},
......@@ -1440,6 +1483,7 @@ var g = &grammar{
pos: position{line: 401, col: 40, offset: 9754},
val: "[",
ignoreCase: false,
want: "\"[\"",
},
&ruleRefExpr{
pos: position{line: 401, col: 44, offset: 9758},
......@@ -1461,6 +1505,7 @@ var g = &grammar{
pos: position{line: 401, col: 64, offset: 9778},
val: "]",
ignoreCase: false,
want: "\"]\"",
},
&ruleRefExpr{
pos: position{line: 401, col: 68, offset: 9782},
......@@ -1507,6 +1552,7 @@ var g = &grammar{
pos: position{line: 418, col: 14, offset: 10128},
val: "//",
ignoreCase: false,
want: "\"//\"",
},
&zeroOrMoreExpr{
pos: position{line: 418, col: 19, offset: 10133},
......@@ -2084,18 +2130,85 @@ var (
// errNoRule is returned when the grammar to parse has no rule.
errNoRule = errors.New("grammar has no rule")
// errInvalidEntrypoint is returned when the specified entrypoint rule
// does not exit.
errInvalidEntrypoint = errors.New("invalid entrypoint")
// errInvalidEncoding is returned when the source is not properly
// utf8-encoded.
errInvalidEncoding = errors.New("invalid encoding")
// errNoMatch is returned if no match could be found.
errNoMatch = errors.New("no match found")
// errMaxExprCnt is used to signal that the maximum number of
// expressions have been parsed.
errMaxExprCnt = errors.New("max number of expresssions parsed")
)
// Option is a function that can set an option on the parser. It returns
// the previous setting as an Option.
type Option func(*parser) Option
// MaxExpressions creates an Option to stop parsing after the provided
// number of expressions have been parsed, if the value is 0 then the parser will
// parse for as many steps as needed (possibly an infinite number).
//
// The default for maxExprCnt is 0.
func MaxExpressions(maxExprCnt uint64) Option {
return func(p *parser) Option {
oldMaxExprCnt := p.maxExprCnt
p.maxExprCnt = maxExprCnt
return MaxExpressions(oldMaxExprCnt)
}
}
// Entrypoint creates an Option to set the rule name to use as entrypoint.
// The rule name must have been specified in the -alternate-entrypoints
// if generating the parser with the -optimize-grammar flag, otherwise
// it may have been optimized out. Passing an empty string sets the
// entrypoint to the first rule in the grammar.
//
// The default is to start parsing at the first rule in the grammar.
func Entrypoint(ruleName string) Option {
return func(p *parser) Option {
oldEntrypoint := p.entrypoint
p.entrypoint = ruleName
if ruleName == "" {
p.entrypoint = g.rules[0].name
}
return Entrypoint(oldEntrypoint)
}
}
// Statistics adds a user provided Stats struct to the parser to allow
// the user to process the results after the parsing has finished.
// Also the key for the "no match" counter is set.
//
// Example usage:
//
// input := "input"
// stats := Stats{}
// _, err := Parse("input-file", []byte(input), Statistics(&stats, "no match"))
// if err != nil {
// log.Panicln(err)
// }
// b, err := json.MarshalIndent(stats.ChoiceAltCnt, "", " ")
// if err != nil {
// log.Panicln(err)
// }
// fmt.Println(string(b))
//
func Statistics(stats *Stats, choiceNoMatch string) Option {
return func(p *parser) Option {
oldStats := p.Stats
p.Stats = stats
oldChoiceNoMatch := p.choiceNoMatch
p.choiceNoMatch = choiceNoMatch
if p.Stats.ChoiceAltCnt == nil {
p.Stats.ChoiceAltCnt = make(map[string]map[string]int)
}
return Statistics(oldStats, oldChoiceNoMatch)
}
}
// Debug creates an Option to set the debug flag to b. When set to true,
// debugging information is printed to stdout while parsing.
//
......@@ -2122,6 +2235,20 @@ func Memoize(b bool) Option {
}
}
// AllowInvalidUTF8 creates an Option to allow invalid UTF-8 bytes.
// Every invalid UTF-8 byte is treated as a utf8.RuneError (U+FFFD)
// by character class matchers and is matched by the any matcher.
// The returned matched value, c.text and c.offset are NOT affected.
//
// The default is false.
func AllowInvalidUTF8(b bool) Option {
return func(p *parser) Option {
old := p.allowInvalidUTF8
p.allowInvalidUTF8 = b
return AllowInvalidUTF8(old)
}
}
// Recover creates an Option to set the recover flag to b. When set to
// true, this causes the parser to recover from panics and convert it
// to an error. Setting it to false can be useful while debugging to
......@@ -2136,13 +2263,37 @@ func Recover(b bool) Option {
}
}
// GlobalStore creates an Option to set a key to a certain value in
// the globalStore.
func GlobalStore(key string, value interface{}) Option {
return func(p *parser) Option {
old := p.cur.globalStore[key]
p.cur.globalStore[key] = value
return GlobalStore(key, old)
}
}
// InitState creates an Option to set a key to a certain value in
// the global "state" store.
func InitState(key string, value interface{}) Option {
return func(p *parser) Option {
old := p.cur.state[key]
p.cur.state[key] = value
return InitState(key, old)
}
}
// ParseFile parses the file identified by filename.
func ParseFile(filename string, opts ...Option) (interface{}, error) {
func ParseFile(filename string, opts ...Option) (i interface{}, err error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
defer func() {
if closeErr := f.Close(); closeErr != nil {
err = closeErr
}
}()
return ParseReader(filename, f, opts...)
}
......@@ -2169,7 +2320,7 @@ type position struct {
}
func (p position) String() string {
return fmt.Sprintf("%d:%d [%d]", p.line, p.col, p.offset)
return strconv.Itoa(p.line) + ":" + strconv.Itoa(p.col) + " [" + strconv.Itoa(p.offset) + "]"
}
// savepoint stores all state required to go back to this point in the
......@@ -2183,8 +2334,22 @@ type savepoint struct {
type current struct {
pos position // start position of the match
text []byte // raw text of the match
// state is a store for arbitrary key,value pairs that the user wants to be
// tied to the backtracking of the parser.
// This is always rolled back if a parsing rule fails.
state storeDict
// globalStore is a general store for the user to store arbitrary key-value
// pairs that they need to manage and that they do not want tied to the
// backtracking of the parser. This is only modified by the user and never
// rolled back by the parser. It is always up to the user to keep this in a
// consistent state.
globalStore storeDict
}
type storeDict map[string]interface{}
// the AST types...
type grammar struct {
......@@ -2210,11 +2375,23 @@ type actionExpr struct {
run func(*parser) (interface{}, error)
}
type recoveryExpr struct {
pos position
expr interface{}
recoverExpr interface{}
failureLabel []string
}
type seqExpr struct {
pos position
exprs []interface{}
}
type throwExpr struct {
pos position
label string
}
type labeledExpr struct {
pos position
label string
......@@ -2237,6 +2414,11 @@ type ruleRefExpr struct {
name string
}
type stateCodeExpr struct {
pos position
run func(*parser) error
}
type andCodeExpr struct {
pos position
run func(*parser) (bool, error)
......@@ -2251,16 +2433,18 @@ type litMatcher struct {
pos position
val string
ignoreCase bool
want string
}
type charClassMatcher struct {
pos position
val string
chars []rune
ranges []rune
classes []*unicode.RangeTable
ignoreCase bool
inverted bool
pos position
val string
basicLatinChars [128]bool
chars []rune
ranges []rune
classes []*unicode.RangeTable
ignoreCase bool
inverted bool
}
type anyMatcher position
......@@ -2314,9 +2498,10 @@ func (e errList) Error() string {
// parserError wraps an error with a prefix indicating the rule in which
// the error occurred. The original error is stored in the Inner field.
type parserError struct {
Inner error
pos position
prefix string
Inner error
pos position
prefix string
expected []string
}
// Error returns the error message.
......@@ -2326,14 +2511,32 @@ func (p *parserError) Error() string {
// newParser creates a parser with the specified input source and options.
func newParser(filename string, b []byte, opts ...Option) *parser {
stats := Stats{
ChoiceAltCnt: make(map[string]map[string]int),
}
p := &parser{
filename: filename,
errs: new(errList),
data: b,
pt: savepoint{position: position{line: 1}},
recover: true,
cur: current{
state: make(storeDict),
globalStore: make(storeDict),
},
maxFailPos: position{col: 1, line: 1},
maxFailExpected: make([]string, 0, 20),
Stats: &stats,
// start rule is rule [0] unless an alternate entrypoint is specified
entrypoint: g.rules[0].name,
}
p.setOptions(opts)
if p.maxExprCnt == 0 {
p.maxExprCnt = math.MaxUint64
}
return p
}
......@@ -2350,6 +2553,30 @@ type resultTuple struct {
end savepoint
}
const choiceNoMatch = -1
// Stats stores some statistics, gathered during parsing
type Stats struct {
// ExprCnt counts the number of expressions processed during parsing
// This value is compared to the maximum number of expressions allowed
// (set by the MaxExpressions option).
ExprCnt uint64
// ChoiceAltCnt is used to count for each ordered choice expression,
// which alternative is used how may times.
// These numbers allow to optimize the order of the ordered choice expression
// to increase the performance of the parser
//
// The outer key of ChoiceAltCnt is composed of the name of the rule as well
// as the line and the column of the ordered choice.
// The inner key of ChoiceAltCnt is the number (one-based) of the matching alternative.
// For each alternative the number of matches are counted. If an ordered choice does not
// match, a special counter is incremented. The name of this counter is set with
// the parser option Statistics.
// For an alternative to be included in ChoiceAltCnt, it has to match at least once.
ChoiceAltCnt map[string]map[string]int
}