File size: 2,241 Bytes
d46f4a3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package net.minecraft.util.parsing.packrat;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Nullable;

public abstract class ParseState<S> {
    private final Map<ParseState.CacheKey<?>, ParseState.CacheEntry<?>> ruleCache = new HashMap<>();
    private final Dictionary<S> dictionary;
    private final ErrorCollector<S> errorCollector;

    protected ParseState(Dictionary<S> p_331339_, ErrorCollector<S> p_333871_) {
        this.dictionary = p_331339_;
        this.errorCollector = p_333871_;
    }

    public ErrorCollector<S> errorCollector() {
        return this.errorCollector;
    }

    public <T> Optional<T> parseTopRule(Atom<T> p_334307_) {
        Optional<T> optional = this.parse(p_334307_);
        if (optional.isPresent()) {
            this.errorCollector.finish(this.mark());
        }

        return optional;
    }

    public <T> Optional<T> parse(Atom<T> p_335708_) {
        ParseState.CacheKey<T> cachekey = new ParseState.CacheKey<>(p_335708_, this.mark());
        ParseState.CacheEntry<T> cacheentry = this.lookupInCache(cachekey);
        if (cacheentry != null) {
            this.restore(cacheentry.mark());
            return cacheentry.value;
        } else {
            Rule<S, T> rule = this.dictionary.get(p_335708_);
            if (rule == null) {
                throw new IllegalStateException("No symbol " + p_335708_);
            } else {
                Optional<T> optional = rule.parse(this);
                this.storeInCache(cachekey, optional);
                return optional;
            }
        }
    }

    @Nullable
    private <T> ParseState.CacheEntry<T> lookupInCache(ParseState.CacheKey<T> p_333102_) {
        return (ParseState.CacheEntry<T>)this.ruleCache.get(p_333102_);
    }

    private <T> void storeInCache(ParseState.CacheKey<T> p_333772_, Optional<T> p_329813_) {
        this.ruleCache.put(p_333772_, new ParseState.CacheEntry<>(p_329813_, this.mark()));
    }

    public abstract S input();

    public abstract int mark();

    public abstract void restore(int p_331216_);

    static record CacheEntry<T>(Optional<T> value, int mark) {
    }

    static record CacheKey<T>(Atom<T> name, int mark) {
    }
}