/**
* Copyright (c) 2011, 2013 Cloudsmith Inc. and other contributors, as listed below.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cloudsmith
*
*/
package org.cloudsmith.geppetto.pp.dsl.lexer;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.RecognizerSharedState;
import org.antlr.runtime.Token;
/**
* The PPOverridingLexer is used to adapt an external lexer "PPLexer.g" to the parser generated from
* pp.xtext. To maintain sanity, the PPLexer.g is written in terms of keywords named KW_<name> where
* the parser is using KEYWORD_<number> and where numbers change when new terminals/keywords are added
* (with a manual tricky synchronization task as a result).
* As long as the terminals/kewords in PPLexer.g are the same as those in pp.xtext it is sufficient
* to simply transpose them into range. All KW_ tokens will be after the (common) set of RULE_ tokens.
* The lexer starts with token 4 (<4 are special token numbers), and thus the first token
* is KW_INHERITS, which from time to time is given some KEYWORD_nn name (it was KEYWORD_66 for a long time),
* which is then mapped to the token number 4.
*
* When new keywords are introduced in the grammar, a check is required to ensure that that
* the set of tokens is the same, and if "inherits" is the first (have number 4). If a terminal/keyword
* is missing (or one added) this simple transposition will fail miserably, so it is important to check.
*
*/
public class PPOverridingLexer extends PPLexer {
public PPOverridingLexer() {
;
}
public PPOverridingLexer(CharStream input) {
super(input);
}
public PPOverridingLexer(CharStream input, RecognizerSharedState state) {
super(input, state);
}
/**
* {@inheritDoc}
*
*/
@Override
public void mTokens() throws RecognitionException {
// Does nothing - but is useful when debugging (set breakpoint here, the super impl is used in more
// than one lexer subclass.
//
super.mTokens();
}
/**
* {@inheritDoc}
* <p>
* This override keeps track of 'last significant token' as this is required as a predicate for other token rules. The remembered token is
* remembered in the token range used by the external lexer (i.e. unmapped from KW_ range to KEYWORD_ range).
* </p>
*/
@Override
public Token nextToken() {
Token t = super.nextToken();
// This translates all KW_ to the KEYWORD range, i.e. KW_INHERTIS (84) KEYWORD_66 (inherits) = 4
int origType = t.getType();
if(origType >= KW_INHERITS)
t.setType(origType - KW_INHERITS + 4);
// System.err.println("Token: " + t.toString());
switch(origType) {
case RULE_SL_COMMENT:
case RULE_ML_COMMENT:
case RULE_WS:
break; // uninteresting tokens
default:
this.lastSignificantToken = origType;
}
return t;
}
}