@@ -48,6 +48,10 @@ protected Token peek(int offset) {
4848 tokens .get (targetPos ) : null ;
4949 }
5050
51+ protected boolean canKeywordBeMethodName (String keywordText ) {
52+ return keywordText .equals ("in" );
53+ }
54+
5155 // NEW: Fast lookahead helpers
5256 protected Token lookahead (int n ) {
5357 return peek (n );
@@ -98,8 +102,7 @@ protected Token consume(TokenType expectedType) {
98102 }
99103 return token ;
100104 }
101- throw new ParseError ("Expected " + getTypeName (expectedType ) + " but found " +
102- getTypeName (token .type ) + " ('" + token .text + "') at line " + token .line + ":" + token .column );
105+ throw new ParseError ("Expected " + getTypeName (expectedType ) + " but found " + getTypeName (token .type ) + " ('" + token .text + "')" , token .line , token .column );
103106 }
104107
105108 protected Token consume (Symbol expectedSymbol ) {
@@ -111,15 +114,14 @@ protected Token consume(Symbol expectedSymbol) {
111114 return token ;
112115 }
113116 throw new ParseError ("Expected " + expectedSymbol + " but found " +
114- getTypeName (token .type ) + " ('" + token .text + "') at line " + token .line + ":" + token .column );
117+ getTypeName (token .type ) + " ('" + token .text + "')" , token .line , token .column );
115118 }
116119
117120 protected Token consume (boolean condition ) {
118121 if (condition ) return consume ();
119122 Token current = currentToken ();
120123 throw new ParseError ("Consumption condition not met at: " + current .text +
121- " (" + getTypeName (current .type ) + ")" +
122- " at line " + current .line + ":" + current .column );
124+ " (" + getTypeName (current .type ) + ")" , current .line , current .column );
123125 }
124126
125127 protected boolean tryConsume (Symbol expectedSymbol ) {
@@ -159,7 +161,7 @@ protected void consumeKeyword(Keyword expectedKeyword) {
159161 return ;
160162 }
161163 throw new ParseError ("Expected keyword '" + expectedKeyword .toString () + "' but found " +
162- getTypeName (token .type ) + " ('" + token .text + "') at line " + token .line + ":" + token .column );
164+ getTypeName (token .type ) + " ('" + token .text + "') " , token .line , token .column );
163165 }
164166
165167 protected boolean isSymbolAt (int offset , Symbol symbol ) {
@@ -189,22 +191,34 @@ protected boolean isExpressionStart(Token t) {
189191 (t .type == KEYWORD && (
190192 NULL .toString ().equals (text ) ||
191193 TRUE .toString ().equals (text ) ||
192- FALSE .toString ().equals (text ) ||
193- INPUT .toString ().equals (text )
194+ FALSE .toString ().equals (text )
194195 ));
195196}
196197
197198 // --- Generic Grammar Helpers ---
198199
199200 protected String parseQualifiedName () {
200- StringBuilder name = new StringBuilder ();
201- name .append (consume (ID ).text );
202- while (tryConsume (DOT )) {
203- name .append ("." );
201+ StringBuilder name = new StringBuilder ();
202+
203+ // First part - must be ID
204+ name .append (consume (ID ).text );
205+
206+ while (tryConsume (DOT )) {
207+ name .append ("." );
208+
209+ // Next part can be ID OR a keyword that can be a method name
210+ Token next = currentToken ();
211+ if (next .type == ID ) {
204212 name .append (consume (ID ).text );
213+ } else if (next .type == KEYWORD && canKeywordBeMethodName (next .text )) {
214+ name .append (consume ().text ); // consume the keyword
215+ } else {
216+ throw new ParseError ("Expected identifier or method keyword after '.', found: " +
217+ getTypeName (next .type ) + " ('" + next .text + "')" , next .line , next .column );
205218 }
206- return name .toString ();
207219 }
220+ return name .toString ();
221+ }
208222
209223 protected boolean isTypeKeyword (String text ) {
210224 // Includes ARRAY keyword for declaration purposes
@@ -329,8 +343,7 @@ protected String parseTypeReference() {
329343 } else {
330344 Token current = currentToken ();
331345 throw new ParseError ("Expected type name but got " +
332- getTypeName (current .type ) + " ('" + current .text + "')" +
333- " at line " + current .line + ":" + current .column );
346+ getTypeName (current .type ) + " ('" + current .text + "')" , current .line , current .column );
334347 }
335348 }
336349
@@ -377,4 +390,4 @@ protected boolean isVisibilityModifier() {
377390 public int getPosition () {
378391 return this .position .get ();
379392 }
380- }
393+ }
0 commit comments