MatchMixed matches mixed tokens and non-tokens
(ps *State, parAST *AST, scope lexer.Reg, depth int, optMap lexer.TokenMap)
| 924 | |
| 925 | // MatchMixed matches mixed tokens and non-tokens |
| 926 | func (pr *Rule) MatchMixed(ps *State, parAST *AST, scope lexer.Reg, depth int, optMap lexer.TokenMap) (bool, Matches) { |
| 927 | nr := len(pr.Rules) |
| 928 | var mpos Matches |
| 929 | |
| 930 | scstlx := ps.Src.LexAt(scope.St) // scope starting lex |
| 931 | scstDepth := scstlx.Token.Depth |
| 932 | |
| 933 | creg := scope |
| 934 | osz := len(pr.Order) |
| 935 | |
| 936 | // first pass filter on tokens |
| 937 | if optMap != nil { |
| 938 | for oi := 0; oi < osz; oi++ { |
| 939 | ri := pr.Order[oi] |
| 940 | rr := &pr.Rules[ri] |
| 941 | if rr.IsToken() { |
| 942 | kt := rr.Token |
| 943 | if !optMap.Has(kt.Token) { // not even a possibility |
| 944 | return false, nil |
| 945 | } |
| 946 | } |
| 947 | } |
| 948 | } |
| 949 | |
| 950 | for oi := 0; oi < osz; oi++ { |
| 951 | ri := pr.Order[oi] |
| 952 | rr := &pr.Rules[ri] |
| 953 | |
| 954 | ///////////////////////////////////////////// |
| 955 | // Token |
| 956 | if rr.IsToken() { |
| 957 | kt := rr.Token |
| 958 | if rr.FromNext { |
| 959 | if mpos == nil { |
| 960 | mpos = make(Matches, nr) // make on demand -- cuts out a lot of allocations! |
| 961 | } |
| 962 | mpos[nr-1] = lexer.Reg{scope.Ed, scope.Ed} |
| 963 | } |
| 964 | kt.Depth += scstDepth // always use starting scope depth |
| 965 | match, tpos := pr.MatchToken(ps, rr, ri, kt, &creg, mpos, parAST, scope, depth, optMap) |
| 966 | if !match { |
| 967 | if ps.Trace.On { |
| 968 | if tpos != lexer.PosZero { |
| 969 | tlx := ps.Src.LexAt(tpos) |
| 970 | ps.Trace.Out(ps, pr, NoMatch, creg.St, creg, parAST, fmt.Sprintf("%v token: %v, was: %v", ri, kt.String(), tlx.String())) |
| 971 | } else { |
| 972 | ps.Trace.Out(ps, pr, NoMatch, creg.St, creg, parAST, fmt.Sprintf("%v token: %v, nil region", ri, kt.String())) |
| 973 | } |
| 974 | } |
| 975 | return false, nil |
| 976 | } |
| 977 | if mpos == nil { |
| 978 | mpos = make(Matches, nr) // make on demand -- cuts out a lot of allocations! |
| 979 | } |
| 980 | mpos[ri] = lexer.Reg{tpos, tpos} |
| 981 | if ps.Trace.On { |
| 982 | ps.Trace.Out(ps, pr, SubMatch, creg.St, creg, parAST, fmt.Sprintf("%v token: %v", ri, kt.String())) |
| 983 | } |