22using EsotericDevZone . RuleBasedParser . Presets ;
33using System ;
44using System . Collections . Generic ;
5+ using System . Diagnostics ;
56using System . Linq ;
7+ using System . Web ;
68
79namespace EsotericDevZone . RuleBasedParser
810{
@@ -32,13 +34,13 @@ public object Parse(string input)
3234 try
3335 {
3436 var tokens = input . SplitToTokens ( TokensSplitOptions , CommentStyle ) ;
37+ tokens . ForEach ( _ => Debug . WriteLine ( _ ) ) ;
3538
3639 if ( tokens . Count == 0 )
3740 {
3841 throw new NoTokensProvidedException ( "No tokens provided" ) ;
3942 }
40-
41- //tokens.ForEach(Console.WriteLine);
43+
4244 var result = LookFor ( RootRuleKey , tokens , 0 ) ;
4345 if ( result != null )
4446 {
@@ -59,7 +61,7 @@ public object Parse(string input)
5961
6062 private ParseRecord LookFor ( ParseRule rule , List < Token > tokens , int pos )
6163 {
62- //Console .WriteLine($"{pos,5}. Looking for {rule}");
64+ Debug . WriteLine ( $ "{ pos , 5 } . Looking for { rule } ") ;
6365
6466 var pattern = rule . ParsePattern ;
6567
@@ -71,70 +73,71 @@ private ParseRecord LookFor(ParseRule rule, List<Token> tokens, int pos)
7173
7274
7375 Exception raisedException = null ;
76+
77+ int originalPos = pos ;
7478
75- int tailReturn = - 1 ;
76- int originalPos = pos ;
77- int i = 0 ;
78- for ( i = 0 ; i < pattern . Length ; i ++ )
79- {
80- var item = pattern [ i ] ;
79+ var mandatoryPattern = pattern . TakeWhile ( _ => ! ( _ is RepeatableTailItem ) ) . ToArray ( ) ;
80+ var optionalPattern = pattern . SkipWhile ( _ => ! ( _ is RepeatableTailItem ) ) . ToArray ( ) . Skip ( 1 ) . ToArray ( ) ;
8181
82- if ( item is RepeatableTailItem )
83- {
84- tailReturn = i ;
82+ Debug . WriteLine ( $ "Mandatory = { string . Join ( " " , mandatoryPattern . ToList ( ) ) } ") ;
83+ Debug . WriteLine ( $ "Optional = { string . Join ( " " , optionalPattern . ToList ( ) ) } ") ;
8584
86- finalRecords = records . ToList ( ) ;
87- finalSelectorMatches = selectorsMatches . ToList ( ) ;
88- continue ;
89- }
90-
91- try
85+ void dealWithPatternItem ( IParseRulePatternItem item )
86+ {
87+ if ( pos >= tokens . Count )
9288 {
93- if ( pos >= tokens . Count )
94- {
95- throw new ParseException ( tokens . Last ( ) , "Insufficient tokens" ) ;
96- }
97-
98- var match = item . Match ( this , tokens , pos ) ;
99- //Console.WriteLine(match);
89+ throw new ParseException ( tokens . Last ( ) , "Insufficient tokens" ) ;
90+ }
10091
101- if ( match is WildcardMatch wildcardMatch )
102- {
103- selectorsMatches . Add ( wildcardMatch . Value ) ;
104- }
105- else if ( match is ParseRecord record )
106- {
107- records . Add ( record ) ;
108- AddToCache ( record ) ;
109- }
110- else if ( match is IgnoreMatch )
111- {
112- }
113- else throw new NotImplementedException ( "Invalid match" ) ;
92+ var match = item . Match ( this , tokens , pos ) ;
11493
115- pos += match . TokensCount ;
94+ if ( match is WildcardMatch wildcardMatch )
95+ {
96+ selectorsMatches . Add ( wildcardMatch . Value ) ;
11697 }
117- catch ( ParseException ex )
98+ else if ( match is ParseRecord record )
11899 {
119- raisedException = ex ;
120- break ;
100+ records . Add ( record ) ;
101+ AddToCache ( record ) ;
121102 }
122-
123- if ( i == pattern . Length - 1 )
103+ else if ( match is IgnoreMatch )
124104 {
125- finalRecords = records . ToList ( ) ;
126- finalSelectorMatches = selectorsMatches . ToList ( ) ;
127- if ( tailReturn >= 0 )
128- {
129- i = tailReturn ;
130- raisedException = null ;
131- }
132- }
105+ }
106+ else throw new NotImplementedException ( "Invalid match" ) ;
107+
108+ pos += match . TokensCount ;
133109 }
134110
135- if ( finalRecords == null || ( raisedException != null && i != tailReturn + 1 ) )
111+ try
136112 {
137- throw raisedException ;
113+ foreach ( var item in mandatoryPattern )
114+ dealWithPatternItem ( item ) ;
115+ }
116+ catch ( ParseException e ) { raisedException = e ; }
117+
118+ if ( raisedException != null ) throw raisedException ;
119+ finalRecords = records . ToList ( ) ;
120+ finalSelectorMatches = selectorsMatches . ToList ( ) ;
121+
122+ int posBackup = pos ;
123+ if ( optionalPattern . Length > 0 && pos < tokens . Count )
124+ {
125+ while ( raisedException == null )
126+ {
127+ posBackup = pos ;
128+ try
129+ {
130+ foreach ( var item in optionalPattern )
131+ dealWithPatternItem ( item ) ;
132+ finalRecords = records . ToList ( ) ;
133+ finalSelectorMatches = selectorsMatches . ToList ( ) ;
134+ }
135+ catch ( ParseException e )
136+ {
137+ raisedException = e ;
138+ }
139+ }
140+ pos = posBackup ;
138141 }
139142
140143 var value = rule . BuildMethod (
@@ -161,6 +164,8 @@ internal ParseRecord LookFor(string ruleKey, List<Token> tokens, int pos)
161164 if ( rec != null )
162165 {
163166 AddToCache ( rec ) ;
167+
168+ //Debug.WriteLine($"Found: {rec.Result.Value}, {rec.Position}:{rec.TokensCount}");
164169 return rec ;
165170 }
166171 }
@@ -182,7 +187,7 @@ internal ParseRecord LookFor(string ruleKey, List<Token> tokens, int pos)
182187 if ( raisedException != null )
183188 throw new ParseException ( raisedException ) ;
184189 //throw new ParseException("Parse failed");
185-
190+
186191 return null ;
187192 }
188193
0 commit comments