Skip to content

Commit 3225e41

Browse files
committed
Merge branch 'transparent' into 0.2.x, stateless code parser updated
2 parents 5620f93 + 1c7acad commit 3225e41

2 files changed

Lines changed: 35 additions & 57 deletions

File tree

src/main/java/com/github/pfmiles/dropincc/impl/runtime/impl/CodeParser.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
* @author pf-miles
2525
*
2626
*/
27-
public abstract class CodeParser extends Parser {
27+
public abstract class CodeParser extends Parser implements Cloneable {
2828

2929
protected CodeLexer lexer;
3030

@@ -89,4 +89,16 @@ protected DelayedAction newDelayedAction(Object action, Object matched) {
8989
}
9090
return new DelayedAction(action, matched);
9191
}
92+
93+
protected CodeParser clone() {
94+
CodeParser ret = null;
95+
try {
96+
ret = (CodeParser) super.clone();
97+
} catch (CloneNotSupportedException e) {
98+
throw new DropinccException(e);
99+
}
100+
// reset all states
101+
ret.parseCache = new HashMap<ParseCacheKey, Pair<DelayedAction, Integer>>();
102+
return ret;
103+
}
92104
}

src/main/java/com/github/pfmiles/dropincc/impl/runtime/impl/StatelessParserPrototype.java

Lines changed: 22 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,9 @@
1111
package com.github.pfmiles.dropincc.impl.runtime.impl;
1212

1313
import java.lang.reflect.Field;
14-
import java.util.ArrayList;
15-
import java.util.HashMap;
16-
import java.util.List;
1714
import java.util.Map;
1815

1916
import com.github.pfmiles.dropincc.DropinccException;
20-
import com.github.pfmiles.dropincc.Predicate;
21-
import com.github.pfmiles.dropincc.impl.TokenType;
2217
import com.github.pfmiles.dropincc.impl.syntactical.codegen.ParserCodeGenResult;
2318

2419
/**
@@ -27,16 +22,9 @@
2722
*/
2823
public class StatelessParserPrototype implements ParserPrototype {
2924

30-
private Class<? extends Parser> parserCls;
31-
32-
private Map<String, TokenType> fieldTokenTypeMapping = new HashMap<String, TokenType>();
33-
private Map<String, Object> fieldAltsActionMapping = new HashMap<String, Object>();
34-
private Map<String, Predicate<?>> fieldPredsMapping = new HashMap<String, Predicate<?>>();
35-
private Map<String, RunningDfaState> fieldRuleDfaMapping = new HashMap<String, RunningDfaState>();
36-
private Map<String, RunningDfaState> fieldKleeneDfaMapping = new HashMap<String, RunningDfaState>();
37-
38-
// parser fields cache
39-
private Map<String, Field> parserFieldsCache = new HashMap<String, Field>();
25+
// because the parser is implemented stateless. So we can reuse the parser
26+
// instance over and over again by cloning it.
27+
private CodeParser parserPrototype;
4028

4129
/**
4230
* Construct a stateless singleton parser prototype by parser class.
@@ -45,57 +33,35 @@ public class StatelessParserPrototype implements ParserPrototype {
4533
* @param parserCodeGenResult
4634
*/
4735
public StatelessParserPrototype(Class<? extends Parser> cls, ParserCodeGenResult parserCodeGenResult) {
48-
this.parserCls = cls;
49-
this.fieldAltsActionMapping = parserCodeGenResult.getFieldAltsActionMapping();
50-
this.fieldKleeneDfaMapping = parserCodeGenResult.getFieldKleeneDfaMapping();
51-
this.fieldPredsMapping = parserCodeGenResult.getFieldPredsMapping();
52-
this.fieldRuleDfaMapping = parserCodeGenResult.getFieldRuleDfaMapping();
53-
this.fieldTokenTypeMapping = parserCodeGenResult.getFieldTokenTypeMapping();
54-
// init fields cache
55-
List<String> allFields = new ArrayList<String>();
56-
allFields.addAll(this.fieldAltsActionMapping.keySet());
57-
allFields.addAll(this.fieldKleeneDfaMapping.keySet());
58-
allFields.addAll(this.fieldPredsMapping.keySet());
59-
allFields.addAll(this.fieldRuleDfaMapping.keySet());
60-
allFields.addAll(this.fieldTokenTypeMapping.keySet());
61-
for (String fname : allFields) {
62-
try {
63-
Field f = cls.getField(fname);
64-
f.setAccessible(true);// this boosts reflection
65-
this.parserFieldsCache.put(fname, f);
66-
} catch (Exception e) {
67-
throw new DropinccException(e);
68-
}
36+
try {
37+
this.parserPrototype = (CodeParser) cls.newInstance();
38+
} catch (Exception e) {
39+
throw new DropinccException(e);
6940
}
41+
// setting all compiled results
42+
mappingField(cls, parserPrototype, parserCodeGenResult.getFieldAltsActionMapping());
43+
mappingField(cls, parserPrototype, parserCodeGenResult.getFieldKleeneDfaMapping());
44+
mappingField(cls, parserPrototype, parserCodeGenResult.getFieldPredsMapping());
45+
mappingField(cls, parserPrototype, parserCodeGenResult.getFieldRuleDfaMapping());
46+
mappingField(cls, parserPrototype, parserCodeGenResult.getFieldTokenTypeMapping());
47+
7048
}
7149

7250
// setting fields' values of obj by field name to value mapping
73-
private void mappingField(Object obj, Map<String, ?> fieldToValue) {
74-
for (Map.Entry<String, ?> e : fieldToValue.entrySet()) {
75-
Field f = this.parserFieldsCache.get(e.getKey());
76-
try {
77-
// those fields are public
51+
private void mappingField(Class<?> cls, Object obj, Map<String, ?> fieldToValue) {
52+
try {
53+
for (Map.Entry<String, ?> e : fieldToValue.entrySet()) {
54+
Field f = cls.getField(e.getKey());
55+
f.setAccessible(true);
7856
f.set(obj, e.getValue());
79-
} catch (Exception ex) {
80-
throw new DropinccException(ex);
8157
}
58+
} catch (Exception ex) {
59+
throw new DropinccException(ex);
8260
}
8361
}
8462

8563
public Parser create(Lexer lexer) {
86-
Parser parser = null;
87-
try {
88-
parser = parserCls.newInstance();
89-
} catch (Exception e) {
90-
throw new DropinccException(e);
91-
}
92-
// setting all compiled results
93-
mappingField(parser, this.fieldAltsActionMapping);
94-
mappingField(parser, this.fieldKleeneDfaMapping);
95-
mappingField(parser, this.fieldPredsMapping);
96-
mappingField(parser, this.fieldRuleDfaMapping);
97-
mappingField(parser, this.fieldTokenTypeMapping);
98-
64+
Parser parser = this.parserPrototype.clone();
9965
parser.setLexer(lexer);
10066
return parser;
10167
}

0 commit comments

Comments
 (0)