mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-17 05:17:53 +08:00
parse: Expose Parser.
This commit is contained in:
parent
121a7b6a36
commit
35a34f36f1
|
@ -17,7 +17,7 @@ func (n *Chunk) addToPipelines(ch *Pipeline) {
|
|||
addChild(n, ch)
|
||||
}
|
||||
|
||||
func ParseChunk(ps *parser) *Chunk {
|
||||
func ParseChunk(ps *Parser) *Chunk {
|
||||
n := &Chunk{node: node{begin: ps.pos}}
|
||||
n.parse(ps)
|
||||
n.end = ps.pos
|
||||
|
@ -42,7 +42,7 @@ func (n *Pipeline) addToForms(ch *Form) {
|
|||
addChild(n, ch)
|
||||
}
|
||||
|
||||
func ParsePipeline(ps *parser) *Pipeline {
|
||||
func ParsePipeline(ps *Parser) *Pipeline {
|
||||
n := &Pipeline{node: node{begin: ps.pos}}
|
||||
n.parse(ps)
|
||||
n.end = ps.pos
|
||||
|
@ -97,7 +97,7 @@ func (n *Form) setExitusRedir(ch *ExitusRedir) {
|
|||
addChild(n, ch)
|
||||
}
|
||||
|
||||
func ParseForm(ps *parser) *Form {
|
||||
func ParseForm(ps *Parser) *Form {
|
||||
n := &Form{node: node{begin: ps.pos}}
|
||||
n.parse(ps)
|
||||
n.end = ps.pos
|
||||
|
@ -127,7 +127,7 @@ func (n *Assignment) setRight(ch *Compound) {
|
|||
addChild(n, ch)
|
||||
}
|
||||
|
||||
func ParseAssignment(ps *parser) *Assignment {
|
||||
func ParseAssignment(ps *Parser) *Assignment {
|
||||
n := &Assignment{node: node{begin: ps.pos}}
|
||||
n.parse(ps)
|
||||
n.end = ps.pos
|
||||
|
@ -152,7 +152,7 @@ func (n *ExitusRedir) setDest(ch *Compound) {
|
|||
addChild(n, ch)
|
||||
}
|
||||
|
||||
func ParseExitusRedir(ps *parser) *ExitusRedir {
|
||||
func ParseExitusRedir(ps *Parser) *ExitusRedir {
|
||||
n := &ExitusRedir{node: node{begin: ps.pos}}
|
||||
n.parse(ps)
|
||||
n.end = ps.pos
|
||||
|
@ -182,7 +182,7 @@ func (n *Redir) setRight(ch *Compound) {
|
|||
addChild(n, ch)
|
||||
}
|
||||
|
||||
func ParseRedir(ps *parser, dest *Compound) *Redir {
|
||||
func ParseRedir(ps *Parser, dest *Compound) *Redir {
|
||||
n := &Redir{node: node{begin: ps.pos}}
|
||||
n.parse(ps, dest)
|
||||
n.end = ps.pos
|
||||
|
@ -207,7 +207,7 @@ func (n *Compound) addToIndexings(ch *Indexing) {
|
|||
addChild(n, ch)
|
||||
}
|
||||
|
||||
func ParseCompound(ps *parser, head bool) *Compound {
|
||||
func ParseCompound(ps *Parser, head bool) *Compound {
|
||||
n := &Compound{node: node{begin: ps.pos}}
|
||||
n.parse(ps, head)
|
||||
n.end = ps.pos
|
||||
|
@ -237,7 +237,7 @@ func (n *Indexing) addToIndicies(ch *Array) {
|
|||
addChild(n, ch)
|
||||
}
|
||||
|
||||
func ParseIndexing(ps *parser, head bool) *Indexing {
|
||||
func ParseIndexing(ps *Parser, head bool) *Indexing {
|
||||
n := &Indexing{node: node{begin: ps.pos}}
|
||||
n.parse(ps, head)
|
||||
n.end = ps.pos
|
||||
|
@ -262,7 +262,7 @@ func (n *Array) addToCompounds(ch *Compound) {
|
|||
addChild(n, ch)
|
||||
}
|
||||
|
||||
func ParseArray(ps *parser, allowSemicolon bool) *Array {
|
||||
func ParseArray(ps *Parser, allowSemicolon bool) *Array {
|
||||
n := &Array{node: node{begin: ps.pos}}
|
||||
n.parse(ps, allowSemicolon)
|
||||
n.end = ps.pos
|
||||
|
@ -302,7 +302,7 @@ func (n *Primary) addToBraced(ch *Compound) {
|
|||
addChild(n, ch)
|
||||
}
|
||||
|
||||
func ParsePrimary(ps *parser, head bool) *Primary {
|
||||
func ParsePrimary(ps *Parser, head bool) *Primary {
|
||||
n := &Primary{node: node{begin: ps.pos}}
|
||||
n.parse(ps, head)
|
||||
n.end = ps.pos
|
||||
|
@ -332,7 +332,7 @@ func (n *MapPair) setValue(ch *Compound) {
|
|||
addChild(n, ch)
|
||||
}
|
||||
|
||||
func ParseMapPair(ps *parser) *MapPair {
|
||||
func ParseMapPair(ps *Parser) *MapPair {
|
||||
n := &MapPair{node: node{begin: ps.pos}}
|
||||
n.parse(ps)
|
||||
n.end = ps.pos
|
||||
|
|
|
@ -16,7 +16,7 @@ For every node type T, it generates the following:
|
|||
method that sets this field and adds it to the children list.
|
||||
|
||||
* If the type has a parse method that takes a *paser, it genertes a parseT
|
||||
func that takes a *parser and returns *T. The func creates a new instance of
|
||||
func that takes a *Parser and returns *T. The func creates a new instance of
|
||||
*T, sets its begin field, calls its parse method, and set its end and
|
||||
sourceText fields.
|
||||
|
||||
|
@ -52,7 +52,7 @@ func (n *X) addToG(ch *Z) {
|
|||
addChild(n, ch)
|
||||
}
|
||||
|
||||
func ParseX(ps *parser) *X {
|
||||
func ParseX(ps *Parser) *X {
|
||||
n := &X{node: node{begin: ps.pos}}
|
||||
n.parse(ps)
|
||||
n.end = ps.pos
|
||||
|
@ -103,7 +103,7 @@ func (n *{parent}) addTo{field}(ch *{child}) {{
|
|||
def put_parse(out, typename, extraargs):
|
||||
extranames = ', '.join(a.split(' ')[0] for a in extraargs.split(', ')) if extraargs else ''
|
||||
print >>out, '''
|
||||
func Parse{typename}(ps *parser{extraargs}) *{typename} {{
|
||||
func Parse{typename}(ps *Parser{extraargs}) *{typename} {{
|
||||
n := &{typename}{{node: node{{begin: ps.pos}}}}
|
||||
n.parse(ps{extranames})
|
||||
n.end = ps.pos
|
||||
|
@ -140,7 +140,7 @@ def main():
|
|||
put_get(out, in_type)
|
||||
continue
|
||||
m = re.match(
|
||||
r'^func \(.* \*(.*)\) parse\(ps \*parser(.*?)\) {$', line)
|
||||
r'^func \(.* \*(.*)\) parse\(ps \*Parser(.*?)\) {$', line)
|
||||
if m:
|
||||
typename, extraargs = m.groups()
|
||||
put_parse(out, typename, extraargs)
|
||||
|
|
|
@ -64,7 +64,7 @@ type Chunk struct {
|
|||
Pipelines []*Pipeline
|
||||
}
|
||||
|
||||
func (bn *Chunk) parse(ps *parser) {
|
||||
func (bn *Chunk) parse(ps *Parser) {
|
||||
bn.parseSeps(ps)
|
||||
for startsPipeline(ps.peek()) {
|
||||
bn.addToPipelines(ParsePipeline(ps))
|
||||
|
@ -80,7 +80,7 @@ func isPipelineSep(r rune) bool {
|
|||
|
||||
// parseSeps parses pipeline separators along with whitespaces. It returns the
|
||||
// number of pipeline separators parsed.
|
||||
func (bn *Chunk) parseSeps(ps *parser) int {
|
||||
func (bn *Chunk) parseSeps(ps *Parser) int {
|
||||
nseps := 0
|
||||
for {
|
||||
r := ps.peek()
|
||||
|
@ -116,7 +116,7 @@ type Pipeline struct {
|
|||
Background bool
|
||||
}
|
||||
|
||||
func (pn *Pipeline) parse(ps *parser) {
|
||||
func (pn *Pipeline) parse(ps *Parser) {
|
||||
pn.addToForms(ParseForm(ps))
|
||||
for parseSep(pn, ps, '|') {
|
||||
parseSpacesAndNewlines(pn, ps)
|
||||
|
@ -153,7 +153,7 @@ type Form struct {
|
|||
ExitusRedir *ExitusRedir
|
||||
}
|
||||
|
||||
func (fn *Form) parse(ps *parser) {
|
||||
func (fn *Form) parse(ps *Parser) {
|
||||
parseSpaces(fn, ps)
|
||||
for fn.tryAssignment(ps) {
|
||||
parseSpaces(fn, ps)
|
||||
|
@ -231,7 +231,7 @@ func (fn *Form) parse(ps *parser) {
|
|||
// tryAssignment tries to parse an assignment. If succeeded, it adds the parsed
|
||||
// assignment to fn.Assignments and returns true. Otherwise it rewinds the
|
||||
// parser and returns false.
|
||||
func (fn *Form) tryAssignment(ps *parser) bool {
|
||||
func (fn *Form) tryAssignment(ps *Parser) bool {
|
||||
if !startsIndexing(ps.peek(), false) || ps.peek() == '=' {
|
||||
return false
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ type Assignment struct {
|
|||
Right *Compound
|
||||
}
|
||||
|
||||
func (an *Assignment) parse(ps *parser) {
|
||||
func (an *Assignment) parse(ps *Parser) {
|
||||
ps.cut('=')
|
||||
an.setLeft(ParseIndexing(ps, false))
|
||||
head := an.Left.Head
|
||||
|
@ -275,7 +275,7 @@ func (an *Assignment) parse(ps *parser) {
|
|||
an.setRight(ParseCompound(ps, false))
|
||||
}
|
||||
|
||||
func checkVariableInAssignment(p *Primary, ps *parser) bool {
|
||||
func checkVariableInAssignment(p *Primary, ps *Parser) bool {
|
||||
if p.Type == Braced {
|
||||
// XXX don't check further inside braced expression
|
||||
return true
|
||||
|
@ -301,7 +301,7 @@ type ExitusRedir struct {
|
|||
Dest *Compound
|
||||
}
|
||||
|
||||
func (ern *ExitusRedir) parse(ps *parser) {
|
||||
func (ern *ExitusRedir) parse(ps *Parser) {
|
||||
ps.next()
|
||||
ps.next()
|
||||
addSep(ern, ps)
|
||||
|
@ -318,7 +318,7 @@ type Redir struct {
|
|||
Right *Compound
|
||||
}
|
||||
|
||||
func (rn *Redir) parse(ps *parser, dest *Compound) {
|
||||
func (rn *Redir) parse(ps *Parser, dest *Compound) {
|
||||
// The parsing of the Left part is done in Form.parse.
|
||||
if dest != nil {
|
||||
rn.setLeft(dest)
|
||||
|
@ -380,7 +380,7 @@ type Compound struct {
|
|||
Indexings []*Indexing
|
||||
}
|
||||
|
||||
func (cn *Compound) parse(ps *parser, head bool) {
|
||||
func (cn *Compound) parse(ps *Parser, head bool) {
|
||||
cn.tilde(ps)
|
||||
for startsIndexing(ps.peek(), head) {
|
||||
cn.addToIndexings(ParseIndexing(ps, head))
|
||||
|
@ -390,7 +390,7 @@ func (cn *Compound) parse(ps *parser, head bool) {
|
|||
// tilde parses a tilde if there is one. It is implemented here instead of
|
||||
// within Primary since a tilde can only appear as the first part of a
|
||||
// Compound. Elsewhere tildes are barewords.
|
||||
func (cn *Compound) tilde(ps *parser) {
|
||||
func (cn *Compound) tilde(ps *Parser) {
|
||||
if ps.peek() == '~' {
|
||||
ps.next()
|
||||
base := node{nil, ps.pos - 1, ps.pos, "~", nil}
|
||||
|
@ -412,7 +412,7 @@ type Indexing struct {
|
|||
Indicies []*Array
|
||||
}
|
||||
|
||||
func (in *Indexing) parse(ps *parser, head bool) {
|
||||
func (in *Indexing) parse(ps *Parser, head bool) {
|
||||
in.setHead(ParsePrimary(ps, head))
|
||||
for parseSep(in, ps, '[') {
|
||||
if !startsArray(ps.peek()) {
|
||||
|
@ -444,7 +444,7 @@ type Array struct {
|
|||
Semicolons []int
|
||||
}
|
||||
|
||||
func (sn *Array) parse(ps *parser, allowSemicolon bool) {
|
||||
func (sn *Array) parse(ps *Parser, allowSemicolon bool) {
|
||||
parseSep := func() {
|
||||
parseSpacesAndNewlines(sn, ps)
|
||||
if allowSemicolon {
|
||||
|
@ -504,7 +504,7 @@ const (
|
|||
Braced
|
||||
)
|
||||
|
||||
func (pn *Primary) parse(ps *parser, head bool) {
|
||||
func (pn *Primary) parse(ps *Parser, head bool) {
|
||||
r := ps.peek()
|
||||
if !startsPrimary(r, head) {
|
||||
ps.error(errShouldBePrimary)
|
||||
|
@ -545,7 +545,7 @@ func (pn *Primary) parse(ps *parser, head bool) {
|
|||
}
|
||||
}
|
||||
|
||||
func (pn *Primary) singleQuoted(ps *parser) {
|
||||
func (pn *Primary) singleQuoted(ps *Parser) {
|
||||
pn.Type = SingleQuoted
|
||||
ps.next()
|
||||
var buf bytes.Buffer
|
||||
|
@ -570,7 +570,7 @@ func (pn *Primary) singleQuoted(ps *parser) {
|
|||
}
|
||||
}
|
||||
|
||||
func (pn *Primary) doubleQuoted(ps *parser) {
|
||||
func (pn *Primary) doubleQuoted(ps *Parser) {
|
||||
pn.Type = DoubleQuoted
|
||||
ps.next()
|
||||
var buf bytes.Buffer
|
||||
|
@ -672,7 +672,7 @@ func hexToDigit(r rune) (rune, bool) {
|
|||
}
|
||||
}
|
||||
|
||||
func (pn *Primary) variable(ps *parser) {
|
||||
func (pn *Primary) variable(ps *Parser) {
|
||||
pn.Type = Variable
|
||||
defer func() { pn.Value = ps.src[pn.begin+1 : ps.pos] }()
|
||||
ps.next()
|
||||
|
@ -699,7 +699,7 @@ func allowedInVariableName(r rune) bool {
|
|||
r == '-' || r == '_' || r == ':' || r == '&'
|
||||
}
|
||||
|
||||
func (pn *Primary) wildcard(ps *parser) {
|
||||
func (pn *Primary) wildcard(ps *Parser) {
|
||||
pn.Type = Wildcard
|
||||
for isWildcard(ps.peek()) {
|
||||
ps.next()
|
||||
|
@ -711,7 +711,7 @@ func isWildcard(r rune) bool {
|
|||
return r == '*' || r == '?'
|
||||
}
|
||||
|
||||
func (pn *Primary) exitusCapture(ps *parser) {
|
||||
func (pn *Primary) exitusCapture(ps *Parser) {
|
||||
ps.next()
|
||||
ps.next()
|
||||
addSep(pn, ps)
|
||||
|
@ -727,7 +727,7 @@ func (pn *Primary) exitusCapture(ps *parser) {
|
|||
}
|
||||
}
|
||||
|
||||
func (pn *Primary) outputCapture(ps *parser) {
|
||||
func (pn *Primary) outputCapture(ps *Parser) {
|
||||
pn.Type = OutputCapture
|
||||
|
||||
var closer rune
|
||||
|
@ -766,7 +766,7 @@ func (pn *Primary) outputCapture(ps *parser) {
|
|||
// Map = '[' { Space } '&' { Space } ']'
|
||||
// = '[' { Space } { MapPair { Space } } ']'
|
||||
|
||||
func (pn *Primary) lbracket(ps *parser) {
|
||||
func (pn *Primary) lbracket(ps *Parser) {
|
||||
parseSep(pn, ps, '[')
|
||||
parseSpacesAndNewlines(pn, ps)
|
||||
|
||||
|
@ -816,7 +816,7 @@ func (pn *Primary) lbracket(ps *parser) {
|
|||
}
|
||||
|
||||
// lambda parses a lambda expression. The opening brace has been seen.
|
||||
func (pn *Primary) lambda(ps *parser) {
|
||||
func (pn *Primary) lambda(ps *Parser) {
|
||||
pn.Type = Lambda
|
||||
ps.pushCutset()
|
||||
pn.setChunk(ParseChunk(ps))
|
||||
|
@ -828,7 +828,7 @@ func (pn *Primary) lambda(ps *parser) {
|
|||
|
||||
// Braced = '{' Compound { BracedSep Compounds } '}'
|
||||
// BracedSep = { Space | '\n' } [ ',' ] { Space | '\n' }
|
||||
func (pn *Primary) lbrace(ps *parser) {
|
||||
func (pn *Primary) lbrace(ps *Parser) {
|
||||
parseSep(pn, ps, '{')
|
||||
|
||||
if r := ps.peek(); r == ';' || r == '\n' || IsSpace(r) {
|
||||
|
@ -866,7 +866,7 @@ func isBracedSep(r rune) bool {
|
|||
return r == ',' || IsSpaceOrNewline(r)
|
||||
}
|
||||
|
||||
func (pn *Primary) bareword(ps *parser, head bool) {
|
||||
func (pn *Primary) bareword(ps *Parser, head bool) {
|
||||
pn.Type = Bareword
|
||||
defer func() { pn.Value = ps.src[pn.begin:ps.pos] }()
|
||||
for allowedInBareword(ps.peek(), head) {
|
||||
|
@ -899,7 +899,7 @@ type MapPair struct {
|
|||
Key, Value *Compound
|
||||
}
|
||||
|
||||
func (mpn *MapPair) parse(ps *parser) {
|
||||
func (mpn *MapPair) parse(ps *Parser) {
|
||||
parseSep(mpn, ps, '&')
|
||||
|
||||
// Parse key part, cutting on '='.
|
||||
|
@ -930,7 +930,7 @@ func NewSep(src string, begin, end int) *Sep {
|
|||
return &Sep{node{nil, begin, end, src[begin:end], nil}}
|
||||
}
|
||||
|
||||
func addSep(n Node, ps *parser) {
|
||||
func addSep(n Node, ps *Parser) {
|
||||
var begin int
|
||||
ch := n.Children()
|
||||
if len(ch) > 0 {
|
||||
|
@ -941,7 +941,7 @@ func addSep(n Node, ps *parser) {
|
|||
addChild(n, NewSep(ps.src, begin, ps.pos))
|
||||
}
|
||||
|
||||
func parseSep(n Node, ps *parser, sep rune) bool {
|
||||
func parseSep(n Node, ps *Parser, sep rune) bool {
|
||||
if ps.peek() == sep {
|
||||
ps.next()
|
||||
addSep(n, ps)
|
||||
|
@ -950,7 +950,7 @@ func parseSep(n Node, ps *parser, sep rune) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func parseSpaces(n Node, ps *parser) {
|
||||
func parseSpaces(n Node, ps *Parser) {
|
||||
if !IsSpace(ps.peek()) {
|
||||
return
|
||||
}
|
||||
|
@ -961,7 +961,7 @@ func parseSpaces(n Node, ps *parser) {
|
|||
addSep(n, ps)
|
||||
}
|
||||
|
||||
func parseSpacesAndNewlines(n Node, ps *parser) {
|
||||
func parseSpacesAndNewlines(n Node, ps *Parser) {
|
||||
// TODO parse comments here.
|
||||
if !IsSpaceOrNewline(ps.peek()) {
|
||||
return
|
||||
|
|
|
@ -9,10 +9,10 @@ import (
|
|||
"github.com/elves/elvish/util"
|
||||
)
|
||||
|
||||
// parser maintains some mutable states of parsing.
|
||||
// Parser maintains some mutable states of parsing.
|
||||
//
|
||||
// NOTE: The str member is assumed to be valid UF-8.
|
||||
type parser struct {
|
||||
type Parser struct {
|
||||
srcName string
|
||||
src string
|
||||
pos int
|
||||
|
@ -22,12 +22,12 @@ type parser struct {
|
|||
}
|
||||
|
||||
// NewParser creates a new parser from a piece of source text and its name.
|
||||
func NewParser(srcname, src string) *parser {
|
||||
return &parser{srcname, src, 0, 0, []map[rune]int{{}}, Error{}}
|
||||
func NewParser(srcname, src string) *Parser {
|
||||
return &Parser{srcname, src, 0, 0, []map[rune]int{{}}, Error{}}
|
||||
}
|
||||
|
||||
// Done tells the parser that parsing has completed.
|
||||
func (ps *parser) Done() {
|
||||
func (ps *Parser) Done() {
|
||||
if ps.pos != len(ps.src) {
|
||||
ps.error(errUnexpectedRune)
|
||||
}
|
||||
|
@ -35,16 +35,21 @@ func (ps *parser) Done() {
|
|||
|
||||
// Errors gets the parsing errors after calling one of the parse* functions. If
|
||||
// the return value is not nil, it is always of type Error.
|
||||
func (ps *parser) Errors() error {
|
||||
func (ps *Parser) Errors() error {
|
||||
if len(ps.errors.Entries) > 0 {
|
||||
return &ps.errors
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Source returns the source code that is being parsed.
|
||||
func (ps *Parser) Source() string {
|
||||
return ps.src
|
||||
}
|
||||
|
||||
const eof rune = -1
|
||||
|
||||
func (ps *parser) peek() rune {
|
||||
func (ps *Parser) peek() rune {
|
||||
if ps.pos == len(ps.src) {
|
||||
return eof
|
||||
}
|
||||
|
@ -55,14 +60,14 @@ func (ps *parser) peek() rune {
|
|||
return r
|
||||
}
|
||||
|
||||
func (ps *parser) hasPrefix(prefix string) bool {
|
||||
func (ps *Parser) hasPrefix(prefix string) bool {
|
||||
return strings.HasPrefix(ps.src[ps.pos:], prefix)
|
||||
}
|
||||
|
||||
// findWord looks ahead for [a-z]* that is also a valid compound. If the
|
||||
// lookahead fails, it returns an empty string. It is useful for looking for
|
||||
// command leaders.
|
||||
func (ps *parser) findPossibleLeader() string {
|
||||
func (ps *Parser) findPossibleLeader() string {
|
||||
rest := ps.src[ps.pos:]
|
||||
i := strings.IndexFunc(rest, func(r rune) bool {
|
||||
return r < 'a' || r > 'z'
|
||||
|
@ -78,7 +83,7 @@ func (ps *parser) findPossibleLeader() string {
|
|||
return rest[:i]
|
||||
}
|
||||
|
||||
func (ps *parser) next() rune {
|
||||
func (ps *Parser) next() rune {
|
||||
if ps.pos == len(ps.src) {
|
||||
ps.overEOF++
|
||||
return eof
|
||||
|
@ -91,7 +96,7 @@ func (ps *parser) next() rune {
|
|||
return r
|
||||
}
|
||||
|
||||
func (ps *parser) backup() {
|
||||
func (ps *Parser) backup() {
|
||||
if ps.overEOF > 0 {
|
||||
ps.overEOF--
|
||||
return
|
||||
|
@ -100,7 +105,7 @@ func (ps *parser) backup() {
|
|||
ps.pos -= s
|
||||
}
|
||||
|
||||
func (ps *parser) advance(c int) {
|
||||
func (ps *Parser) advance(c int) {
|
||||
ps.pos += c
|
||||
if ps.pos > len(ps.src) {
|
||||
ps.overEOF = ps.pos - len(ps.src)
|
||||
|
@ -108,11 +113,11 @@ func (ps *parser) advance(c int) {
|
|||
}
|
||||
}
|
||||
|
||||
func (ps *parser) errorp(begin, end int, e error) {
|
||||
func (ps *Parser) errorp(begin, end int, e error) {
|
||||
ps.errors.Add(e.Error(), util.SourceContext{ps.srcName, ps.src, begin, end, nil})
|
||||
}
|
||||
|
||||
func (ps *parser) error(e error) {
|
||||
func (ps *Parser) error(e error) {
|
||||
end := ps.pos
|
||||
if end < len(ps.src) {
|
||||
end++
|
||||
|
@ -120,29 +125,29 @@ func (ps *parser) error(e error) {
|
|||
ps.errorp(ps.pos, end, e)
|
||||
}
|
||||
|
||||
func (ps *parser) pushCutset(rs ...rune) {
|
||||
func (ps *Parser) pushCutset(rs ...rune) {
|
||||
ps.cutsets = append(ps.cutsets, map[rune]int{})
|
||||
ps.cut(rs...)
|
||||
}
|
||||
|
||||
func (ps *parser) popCutset() {
|
||||
func (ps *Parser) popCutset() {
|
||||
n := len(ps.cutsets)
|
||||
ps.cutsets[n-1] = nil
|
||||
ps.cutsets = ps.cutsets[:n-1]
|
||||
}
|
||||
|
||||
func (ps *parser) currentCutset() map[rune]int {
|
||||
func (ps *Parser) currentCutset() map[rune]int {
|
||||
return ps.cutsets[len(ps.cutsets)-1]
|
||||
}
|
||||
|
||||
func (ps *parser) cut(rs ...rune) {
|
||||
func (ps *Parser) cut(rs ...rune) {
|
||||
cutset := ps.currentCutset()
|
||||
for _, r := range rs {
|
||||
cutset[r]++
|
||||
}
|
||||
}
|
||||
|
||||
func (ps *parser) uncut(rs ...rune) {
|
||||
func (ps *Parser) uncut(rs ...rune) {
|
||||
cutset := ps.currentCutset()
|
||||
for _, r := range rs {
|
||||
cutset[r]--
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Code generated by "stringer -type=PrimaryType,RedirMode -output=string.go"; DO NOT EDIT
|
||||
// Code generated by "stringer -type=PrimaryType,RedirMode -output=string.go"; DO NOT EDIT.
|
||||
|
||||
package parse
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user