@@ -29,16 +29,29 @@ package com.github.lppedd.cc.parser;
2929 return value;
3030 }
3131
32- private int getWsPushback() {
33- final int length = yylength();
32+ private int getFooterTypePushback() {
33+ int i = yylength() - 1 ;
34+ int pushback = 0 ;
3435
35- for (int i = length - 1 , count = 0 ; i >= 0 ; i-- , count++ ) {
36- if (! Character . isWhitespace(yycharat(i))) {
37- return count;
36+ // Push back trailing whitespace
37+ for (; i >= 0 && Character . isWhitespace(yycharat(i)); i-- , pushback++ );
38+
39+ // Check whether we now have a trailing '#'
40+ while (i >= 0 && yycharat(i) == ' #' ) {
41+ // If '#' is attached (e.g., 'Something#'), keep it as part of the type and stop
42+ if (i - 1 >= 0 && ! Character . isWhitespace(yycharat(i - 1 ))) {
43+ break ;
3844 }
45+
46+ // Since the '#' char is preceeded by a whitespace, push it back
47+ i-- ;
48+ pushback++ ;
49+
50+ // Push back any whitespace before the '#' we have just encountered
51+ for (; i >= 0 && Character . isWhitespace(yycharat(i)); i-- , pushback++ );
3952 }
4053
41- return length ;
54+ return pushback ;
4255 }
4356
4457 private CCToken token(final CCToken . Type type) {
@@ -66,6 +79,7 @@ FooterType = [^\s:][^:\r\n]*
6679%state BODY_OR_FOOTERS
6780%state BODY
6881%state FOOTERS
82+ %state FOOTER_HASH_SEPARATOR
6983%state FOOTER_VALUE
7084
7185%%
@@ -136,9 +150,9 @@ FooterType = [^\s:][^:\r\n]*
136150
137151 // Closes #16
138152 ^ {FooterType}{WS} / #.* {
139- // Push back any terminating whitespace, which should be part of the footer value instead
140- yypushback(getWsPushback ());
141- yybegin(FOOTER_VALUE );
153+ // Push back any trailing whitespace or '#'
154+ yypushback(getFooterTypePushback ());
155+ yybegin(FOOTER_HASH_SEPARATOR );
142156 return token(CCToken . Type . FOOTER_TYPE );
143157 }
144158
@@ -181,9 +195,9 @@ FooterType = [^\s:][^:\r\n]*
181195
182196 // Closes #16
183197 ^ {FooterType}{WS} / #.* {
184- // Push back any terminating whitespace, which should be part of the footer value instead
185- yypushback(getWsPushback ());
186- yybegin(FOOTER_VALUE );
198+ // Push back any trailing whitespace or '#'
199+ yypushback(getFooterTypePushback ());
200+ yybegin(FOOTER_HASH_SEPARATOR );
187201 return token(CCToken . Type . FOOTER_TYPE );
188202 }
189203
@@ -201,6 +215,15 @@ FooterType = [^\s:][^:\r\n]*
201215 }
202216}
203217
218+ <FOOTER_HASH_SEPARATOR> {
219+ // Lex exactly one whitespace as the footer separator token ' '.
220+ // Additional whitespace will be lexed as part of the footer value.
221+ {WS} {
222+ yybegin(FOOTER_VALUE );
223+ return token(CCToken . Type . SEPARATOR );
224+ }
225+ }
226+
204227<FOOTER_VALUE> {
205228 // Closes #16 | .+
206229 // multiline footer | ({NewLine}{Space}+([^\s]+{Space}*)+)*
0 commit comments