aboutsummaryrefslogtreecommitdiffstats
path: root/Application/org.eclipse.viatra.solver.language/src/org/eclipse/viatra/solver/language/parser/antlr/SolverLanguageTokenSource.java
blob: 4c1dacd55667c184766048e04e943b6bd99e71cc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
 * generated by Xtext 2.21.0
 */
package org.eclipse.viatra.solver.language.parser.antlr;

import static org.eclipse.viatra.solver.language.parser.antlr.internal.InternalSolverLanguageParser.RULE_FULL_STOP;
import static org.eclipse.viatra.solver.language.parser.antlr.internal.InternalSolverLanguageParser.RULE_ID;
import static org.eclipse.viatra.solver.language.parser.antlr.internal.InternalSolverLanguageParser.RULE_INT;
import static org.eclipse.viatra.solver.language.parser.antlr.internal.InternalSolverLanguageParser.RULE_ML_COMMENT;
import static org.eclipse.viatra.solver.language.parser.antlr.internal.InternalSolverLanguageParser.RULE_QUOTED_ID;
import static org.eclipse.viatra.solver.language.parser.antlr.internal.InternalSolverLanguageParser.RULE_REFLEXIVE_TRANSITIVE_CLOSURE;
import static org.eclipse.viatra.solver.language.parser.antlr.internal.InternalSolverLanguageParser.RULE_SL_COMMENT;
import static org.eclipse.viatra.solver.language.parser.antlr.internal.InternalSolverLanguageParser.RULE_TRANSITIVE_CLOSURE;
import static org.eclipse.viatra.solver.language.parser.antlr.internal.InternalSolverLanguageParser.RULE_WS;

import java.util.Map;

import org.antlr.runtime.Token;
import org.antlr.runtime.TokenSource;
import org.eclipse.xtext.parser.antlr.ITokenDefProvider;
import org.eclipse.xtext.parser.antlr.TokenAcceptor;

public class SolverLanguageTokenSource implements TokenSource {
	private TokenSource delegate;

	private final TokenAcceptor acceptor = new TokenAcceptor();

	private int lastTokenId = -1;
	private int plusTokenId = -1;
	private int starTokenId = -1;
	private int dotTokenId = -1;
	private int openParenTokenId = -1;

	public SolverLanguageTokenSource(TokenSource delegate) {
		this.delegate = delegate;
	}

	@Override
	public String getSourceName() {
		return "[SolverLanguageSyntheticTokenTokenSource] " + delegate.getSourceName();
	}

	@Override
	public Token nextToken() {
		Token token = internalNextToken();
		lastTokenId = token.getType();
		return token;
	}

	protected Token internalNextToken() {
		if (acceptor.hasNext()) {
			return acceptor.next();
		}
		Token token = delegate.nextToken();
		int type = token.getType();
		if (type == plusTokenId) {
			if ((lastTokenId == RULE_ID || lastTokenId == RULE_QUOTED_ID)
					&& peekUntilVisible().getType() == openParenTokenId) {
				token.setType(RULE_TRANSITIVE_CLOSURE);
			}
		} else if (type == starTokenId) {
			if ((lastTokenId == RULE_ID || lastTokenId == RULE_QUOTED_ID)
					&& peekUntilVisible().getType() == openParenTokenId) {
				token.setType(RULE_REFLEXIVE_TRANSITIVE_CLOSURE);
			}
		} else if (type == dotTokenId) {
			if ((lastTokenId != RULE_ID && lastTokenId != RULE_INT) || peekToken().getType() != lastTokenId) {
				token.setType(RULE_FULL_STOP);
			}
		}
		return token;
	}

	protected Token peekUntilVisible() {
		Token followingToken = null;
		do {
			followingToken = peekToken();
		} while (isHidden(followingToken.getType()));
		return followingToken;
	}

	protected Token peekToken() {
		Token followingToken = delegate.nextToken();
		acceptor.accept(followingToken);
		return followingToken;
	}

	protected boolean isHidden(int tokenType) {
		return tokenType == RULE_WS || tokenType == RULE_SL_COMMENT || tokenType == RULE_ML_COMMENT;
	}

	public void initializeTokenDefsFrom(ITokenDefProvider provider) {
		for (Map.Entry<Integer, String> entry : provider.getTokenDefMap().entrySet()) {
			switch (entry.getValue()) {
			case "'+'":
				plusTokenId = entry.getKey();
				break;
			case "'*'":
				starTokenId = entry.getKey();
				break;
			case "'.'":
				dotTokenId = entry.getKey();
				break;
			case "'('":
				openParenTokenId = entry.getKey();
				break;
			}
		}
		if (plusTokenId == -1) {
			throw new IllegalStateException("Token '+' was not found");
		}
		if (starTokenId == -1) {
			throw new IllegalStateException("Token '*' was not found");
		}
		if (dotTokenId == -1) {
			throw new IllegalStateException("Token '.' was not found");
		}
		if (openParenTokenId == -1) {
			throw new IllegalStateException("Token '(' was not found");
		}
	}
}