1111package com .github .pfmiles .dropincc .impl .runtime .impl ;
1212
1313import java .lang .reflect .Field ;
14- import java .util .ArrayList ;
15- import java .util .HashMap ;
16- import java .util .List ;
1714import java .util .Map ;
1815
1916import com .github .pfmiles .dropincc .DropinccException ;
20- import com .github .pfmiles .dropincc .Predicate ;
21- import com .github .pfmiles .dropincc .impl .TokenType ;
2217import com .github .pfmiles .dropincc .impl .syntactical .codegen .ParserCodeGenResult ;
2318
2419/**
2722 */
2823public 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