blob: 7d83c9f005fd7033eea40d9e41b083dd7a37d055 [file] [log] [blame]
--
--
-- In a parser using this template, the following macro may be redefined:
--
-- $additional_interfaces
-- $ast_class
--
-- B E G I N N I N G O F T E M P L A T E btVTCLParserTemplateD
--
%Options programming_language=java,margin=4,backtrack
%Options table,error_maps,scopes
%options prefix=TK_,
%options action=("*.java", "/.", "./")
%options ParseTable=lpg.lpgjavaruntime.ParseTable
--
-- This template requires that the name of the EOF token be set
-- to EOF_TOKEN to be consistent with LexerTemplateD and LexerTemplateE
--
$EOF
EOF_TOKEN
$End
$ERROR
ERROR_TOKEN
$End
$Define
$Header
/.
//
// Rule $rule_number: $rule_text
//./
$BeginAction
/. $Header
case $rule_number: {./
$EndAction
/. break;
}./
$BeginJava
/.$BeginAction
$symbol_declarations./
$EndJava /.$EndAction./
$NoAction
/. $Header
case $rule_number:
break;./
$BadAction
/. $Header
case $rule_number:
throw new Error("No action specified for rule " + $rule_number);./
$NullAction
/. $Header
case $rule_number:
setResult(null);
break;./
$BeginActions
/.
public void ruleAction(int ruleNumber)
{
switch (ruleNumber)
{./
$SplitActions
/.
default:
ruleAction$rule_number(ruleNumber);
break;
}
return;
}
public void ruleAction$rule_number(int ruleNumber)
{
switch (ruleNumber)
{./
$EndActions
/.
default:
break;
}
return;
}./
--
-- Macros that may be needed in a parser using this template
--
$additional_interfaces /../
$ast_class /.$ast_type./
--
-- Old deprecated macros that should NEVER be used.
--
$setSym1 /. // macro setSym1 is deprecated. Use function setResult
getParser().setSym1./
$setResult /. // macro setResult is deprecated. Use function setResult
getParser().setSym1./
$getSym /. // macro getSym is deprecated. Use function getRhsSym
getParser().getSym./
$getToken /. // macro getToken is deprecated. Use function getRhsTokenIndex
getParser().getToken./
$getIToken /. // macro getIToken is deprecated. Use function getRhsIToken
super.getIToken./
$getLeftSpan /. // macro getLeftSpan is deprecated. Use function getLeftSpan
getParser().getFirstToken./
$getRightSpan /. // macro getRightSpan is deprecated. Use function getRightSpan
getParser().getLastToken./
$End
$Globals
/.import lpg.lpgjavaruntime.*;
./
$End
$Headers
/.
import org.eclipse.viatra2.errors.info.ErrorInformation;
import org.eclipse.viatra2.errors.info.Location;
import org.eclipse.viatra2.lpgparser.loader.VTCLMessages;
import org.eclipse.viatra2.errors.info.ErrorInformation.ErrorKind;
import org.eclipse.viatra2.errors.info.ErrorInformation.ErrorSeverity;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.viatra2.lpgparser.loader.ExplanationGenerator;
public class $action_type extends PrsStream implements RuleAction$additional_interfaces {
final String PARSER_MARKER = "org.eclipse.viatra2.loaders.vtclparsermarker";
ExplanationGenerator generator = new ExplanationGenerator(this);
private java.util.List<ErrorInformation> allErrorInfos = new java.util.ArrayList<ErrorInformation>();
public java.util.List<ErrorInformation> getAllErrorInfos() {
return allErrorInfos;
}
public void clearParseErrorList() {
if (allErrorInfos == null)
allErrorInfos = new java.util.ArrayList<ErrorInformation>();
else
allErrorInfos.clear();
}
private static ParseTable prs = new $prs_type();
private BacktrackingParser btParser;
public BacktrackingParser getParser() { return btParser; }
private void setResult(Object object) { btParser.setSym1(object); }
public Object getRhsSym(int i) { return btParser.getSym(i); }
public int getRhsTokenIndex(int i) { return btParser.getToken(i); }
public IToken getRhsIToken(int i) { return super.getIToken(getRhsTokenIndex(i)); }
public int getRhsFirstTokenIndex(int i) { return btParser.getFirstToken(i); }
public IToken getRhsFirstIToken(int i) { return super.getIToken(getRhsFirstTokenIndex(i)); }
public int getRhsLastTokenIndex(int i) { return btParser.getLastToken(i); }
public IToken getRhsLastIToken(int i) { return super.getIToken(getRhsLastTokenIndex(i)); }
public int getLeftSpan() { return btParser.getFirstToken(); }
public IToken getLeftIToken() { return super.getIToken(getLeftSpan()); }
public int getRightSpan() { return btParser.getLastToken(); }
public IToken getRightIToken() { return super.getIToken(getRightSpan()); }
public int getRhsErrorTokenIndex(int i) {
int index = btParser.getToken(i);
IToken err = super.getIToken(index);
return (err instanceof ErrorToken ? index : 0);
}
public ErrorToken getRhsErrorIToken(int i) {
int index = btParser.getToken(i);
IToken err = super.getIToken(index);
return (ErrorToken) (err instanceof ErrorToken ? err : null);
}
public $action_type(LexStream lexStream) {
super(lexStream);
try {
super.remapTerminalSymbols(orderedTerminalSymbols(), $prs_type.EOFT_SYMBOL);
} catch(NullExportedSymbolsException e) {
} catch(NullTerminalSymbolsException e) {
} catch(UnimplementedTerminalsException e) {
java.util.ArrayList unimplemented_symbols = e.getSymbols();
System.out.println("The Lexer will not scan the following token(s):");
for (int i = 0; i < unimplemented_symbols.size(); i++) {
Integer id = (Integer) unimplemented_symbols.get(i);
System.out.println(" " + $sym_type.orderedTerminalSymbols[id.intValue()]);
}
System.out.println();
}
catch(UndefinedEofSymbolException e) {
throw new Error(new UndefinedEofSymbolException
("The Lexer does not implement the Eof symbol " +
$sym_type.orderedTerminalSymbols[$prs_type.EOFT_SYMBOL]));
}
}
public String[] orderedTerminalSymbols() { return $sym_type.orderedTerminalSymbols; }
public String getTokenKindName(int kind) { return $sym_type.orderedTerminalSymbols[kind]; }
public int getEOFTokenKind() { return $prs_type.EOFT_SYMBOL; }
public PrsStream getParseStream() { return this; }
/**
* Called when encountering a single bad character. Do not report
* this error at this point.
*/
public void reportError(int left_char, int right_char) {
// System.out.println("reportError(int, int)");
}
/**
* Reports the parse error by setting the error to <code>errorString</code>
*
* @param errorCode the error code
* @param locationInfo
* @param leftToken the token to the left of the error
* @param rightToken the token to the right of the error
* @param tokenText the text of the bad token
*/
public void reportError(int errorCode, String locationInfo, int leftToken, int rightToken, String tokenText) {
int leftTokenLoc = (leftToken > rightToken ? rightToken : leftToken);
int rightTokenLoc = rightToken;
String errorString;
if (getLine(leftTokenLoc) <= 0) {
errorString = VTCLMessages.InvalidVTCL_ERROR_;
allErrorInfos.add(new ErrorInformation(errorString, PARSER_MARKER, ErrorKind.PARSE_ERROR));
}
else {
Location location = new Location(
getLine(leftTokenLoc),
getColumn(leftTokenLoc),
getEndLine(rightTokenLoc),
getEndColumn(rightTokenLoc) + 1,
getStartOffset(leftTokenLoc),
getEndOffset(rightTokenLoc));
switch (errorCode) {
case EOF_CODE:
case MISPLACED_CODE:
case DELETION_CODE:
errorString = " Syntax error: " + errorMsgText[errorCode] + " " +
'"' + computeInputString(
getIToken(leftToken).getStartOffset(),
getIToken(rightToken).getEndOffset()) + '"';
break;
case INVALID_TOKEN_CODE:
errorString = " Syntax error: Token" + " " +
'"' + computeInputString(
getIToken(leftToken).getStartOffset(),
getIToken(rightToken).getEndOffset()) + '"'
+ " " + errorMsgText[errorCode] + ".";
String explanation = generator.calculateErrorExplanation(tokenText, leftToken, rightToken);
if (explanation != "") {
errorString = errorString + " Cause: " + explanation + ".";
}
break;
case MERGE_CODE:
case BEFORE_CODE:
case INSERTION_CODE:
case SCOPE_CODE:
case SUBSTITUTION_CODE: // includes SECONDARY_CODE
errorString = " Syntax error: " + tokenText + " " + errorMsgText[errorCode] + " " +
'"' + computeInputString(
getIToken(leftToken).getStartOffset(),
getIToken(rightToken).getEndOffset()) + '"';
break;
default:
errorString = " Syntax error: " + errorMsgText[errorCode] + " at token " + tokenText;
break;
}
allErrorInfos.add(new
ErrorInformation(errorString,
PARSER_MARKER,
ErrorKind.PARSE_ERROR,
location,
ErrorSeverity.ERROR));
}
}
/**
* Returns a single line string representation of the input chars
* for the given range.
*
* @param left left most char index
* @param right right most char index
* @return a single line string representation of the input chars
*/
private String computeInputString(int left, int right) {
StringBuffer result = new StringBuffer(right - left + 1);
char[] chars = getInputChars();
for (int i = left; i <= right; i++) {
if (chars[i] == '\t') {
result.append(' ');
} else if (chars[i] == '\n' || chars[i] == '\r' || chars[i] == '\f') {
if (i > 0) {
if (!Character.isWhitespace(chars[i-1])) {
result.append(' ');
}
}
} else {
result.append(chars[i]);
}
}
return result.toString();
}
/**
* Report error message for given error_token by calling
* method <code>reportError/5</code> is called finally
* @param error_token
* @param msg
*/
public final void reportErrorTokenMessage(int error_token, String msg)
{
allErrorInfos.add(new
ErrorInformation(msg,
PARSER_MARKER,
ErrorKind.PARSE_ERROR,
getLine(error_token),
getColumn(error_token),
getEndLine(error_token),
getEndColumn(error_token)));
}
/**
* This SymbolTable class is from the IMP project
*/
public static class SymbolTable {
private Map<String,ASTNode> table = new HashMap<String,ASTNode>();
public void addDefinition(String name, ASTNode def) { table.put(name, def); }
public ASTNode lookup(String name) { return table.get(name); }
public List<String> allSymbolsOfType(Class type) {
List<String> result= new ArrayList<String>();
for(String sym: table.keySet()) {
ASTNode def= table.get(sym);
if (type.isInstance(def))
result.add(sym);
}
return result;
}
public <T> List<T> allDefsOfType(Class<T> type) {
List<T> result = new ArrayList<T>();
for(String sym: table.keySet()) {
ASTNode def= table.get(sym);
if (type.isInstance(def))
result.add((T) def);
}
return result;
}
public Set<String> allSymbols() { return table.keySet(); }
}
// protected static SymbolTable symtab;
// { symtab = new SymbolTable(); }
public $ast_class parser()
{
return parser(null, 0);
}
public $ast_class parser(Monitor monitor)
{
return parser(monitor, 0);
}
public $ast_class parser(int error_repair_count)
{
return parser(null, error_repair_count);
}
public $ast_class parser(Monitor monitor, int error_repair_count)
{
try
{
btParser = new BacktrackingParser(monitor, this, prs, this);
}
catch (NotBacktrackParseTableException e)
{
throw new Error(new NotBacktrackParseTableException
("Regenerate $prs_type.java with -BACKTRACK option"));
}
catch (BadParseSymFileException e)
{
throw new Error(new BadParseSymFileException("Bad Parser Symbol File -- $sym_type.java"));
}
try
{
return ($ast_class) btParser.parse(error_repair_count);
}
catch (BadParseException e)
{
reset(e.error_token); // point to error token
DiagnoseParser diagnoseParser = new DiagnoseParser(this, prs);
diagnoseParser.diagnose(e.error_token);
}
return null;
}
./
$End
$Rules
/.$BeginActions./
$End
$Trailers
/.
$EndActions
}
./
$End
--
-- E N D O F T E M P L A T E
--