Scope finds the potential scope region for looking for tokens -- either from EOS position or State ScopeStack pushed from parents. Returns new scope and false if no valid scope found.
(ps *State, parAST *AST, scope lexer.Reg)
| 707 | // EOS position or State ScopeStack pushed from parents. |
| 708 | // Returns new scope and false if no valid scope found. |
| 709 | func (pr *Rule) Scope(ps *State, parAST *AST, scope lexer.Reg) (lexer.Reg, bool) { |
| 710 | // prf := profile.Start("Scope") |
| 711 | // defer prf.End() |
| 712 | |
| 713 | nscope := scope |
| 714 | creg := scope |
| 715 | lr := pr.Rules.Last() |
| 716 | for ei := 0; ei < lr.StInc; ei++ { |
| 717 | stlx := ps.Src.LexAt(creg.St) |
| 718 | ep, ok := ps.Src.NextEos(creg.St, stlx.Token.Depth) |
| 719 | if !ok { |
| 720 | // ps.Error(creg.St, "could not find EOS at target nesting depth -- parens / bracket / brace mismatch?", pr) |
| 721 | return nscope, false |
| 722 | } |
| 723 | if scope.Ed != lexer.PosZero && lr.Opt && scope.Ed.IsLess(ep) { |
| 724 | // optional tokens can't take us out of scope |
| 725 | return scope, true |
| 726 | } |
| 727 | if ei == lr.StInc-1 { |
| 728 | nscope.Ed = ep |
| 729 | if ps.Trace.On { |
| 730 | ps.Trace.Out(ps, pr, SubMatch, nscope.St, nscope, parAST, fmt.Sprintf("from EOS: starting scope: %v new scope: %v end pos: %v depth: %v", scope, nscope, ep, stlx.Token.Depth)) |
| 731 | } |
| 732 | } else { |
| 733 | creg.St, ok = ps.Src.NextTokenPos(ep) // advance |
| 734 | if !ok { |
| 735 | // ps.Error(scope.St, "end of file looking for EOS tokens -- premature file end?", pr) |
| 736 | return nscope, false |
| 737 | } |
| 738 | } |
| 739 | } |
| 740 | return nscope, true |
| 741 | } |
| 742 | |
| 743 | // Match attempts to match the rule, returns true if it matches, and the |
| 744 | // match positions, along with any update to the scope |