source: java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/FramScriptAuxiliaryLexer.java @ 440

Last change on this file since 440 was 440, checked in by Mateusz Poszwa, 9 years ago
  • Updated Xtext-based Framclipse
  • Deleted previous version of Framclipse
  • Property svn:eol-style set to native
File size: 5.8 KB
Line 
1package com.framsticks.framclipse;
2
3import org.antlr.runtime.CharStream;
4import org.antlr.runtime.RecognitionException;
5import org.antlr.runtime.Token;
6
7import com.framsticks.framclipse.parser.antlr.internal.InternalFramScriptLexer;
8
9public class FramScriptAuxiliaryLexer extends InternalFramScriptLexer {
10
11        private static final int FLG_MULTILINE = 0x1;
12        private static final int FLG_TYPE_IS_NUMERIC = 0x2;     // if raised, the default value should be analysed with internal lexer
13        private static final int FLG_TYPE_IS_STRING = 0x4;      // if raised, the max value can be omitted and should be 0
14        private static final int CTX_NONE = 0;
15        private static final int CTX_TYPE = 1;
16        private static final int CTX_TYPE_ID = 2;
17        private static final int CTX_TYPE_MIN = 3;
18        private static final int CTX_TYPE_MAX = 4;
19        private static final int CTX_TYPE_DEFAULT = 5;
20
21        private int context = CTX_NONE;
22        private int flags = 0;
23        private Token previous = Token.INVALID_TOKEN;
24
25        private void checkML() {
26                setFlag(FLG_MULTILINE, next() == '~');
27        }
28
29        private boolean isSet(int flag) {
30                return (flags & flag) != 0;
31        }
32
33        private void setFlag(int flag, boolean state) {
34                if (state)
35                        flags |= flag;
36                else
37                        flags &= ~flag;
38        }
39
40        private void setState(int tokenType) {
41                state.token = null;
42                state.channel = Token.DEFAULT_CHANNEL;
43                state.tokenStartCharIndex = input.index();
44                state.tokenStartCharPositionInLine = input.getCharPositionInLine();
45                state.tokenStartLine = input.getLine();
46                state.text = null;
47                state.type = tokenType;
48        }
49
50        char next() {
51                return next(1);
52        }
53
54        char next(int i) {
55                return (char)input.LA(i);
56        }
57
58        void consumeUntilAny(String term) {
59                term += (char)CharStream.EOF;
60                while (term.indexOf(next()) == -1)
61                        matchAny();
62        }
63
64        @Override
65        public Token nextToken() {
66                switch (previous.getType()) {
67                case RULE_HEADER_ID:
68                        setState(RULE_HEADER_VALUE);
69                        checkML();
70                        mHEADER_VALUE();
71                        return previous = emit();
72                case RULE_TYPE_HEADER:
73                        checkML();
74                        context = CTX_TYPE;
75                        if (isSet(FLG_MULTILINE)) {
76                                setState(RULE_WS);      // any ignored token
77                                matchAny();     // consume '~'
78                                return previous = emit();
79                        }
80                        break;
81                case RULE_WS:
82                        if (context == CTX_TYPE_MIN) {
83                                if (isSet(FLG_TYPE_IS_STRING)) {
84                                        if (!Character.isDigit(next()) && next() != '-') {      // if string length is omitted
85                                                if (isSet(FLG_MULTILINE))
86                                                        matchAny();     // ignore expected '~'
87                                                setState(RULE_INT);
88                                                state.text = "0";       // pretend the max value is 0
89                                                return previous = emit();
90                                        }
91                                }
92                        }
93                        if (previous.getText().indexOf('\n') != -1 ||
94                                        previous.getText().indexOf('\r') != -1) {
95                                if (!isSet(FLG_MULTILINE)) {
96                                        context = CTX_NONE;
97                                }
98                                // workaround for '#include'
99                                if (willMatch("#include")) {
100                                        setState(RULE_PROP_INCLUDE);
101                                        try {
102                                                mRULE_PROP_INCLUDE();
103                                        } catch (RecognitionException e) {
104                                                reportError(e);
105                                        }
106                                        return previous = emit();
107                                }
108                                if (!isSet(FLG_MULTILINE)) {
109                                        break;
110                                }
111                        }
112                        if (context == CTX_TYPE_MAX) {
113                                if (isSet(FLG_MULTILINE)) {
114                                        context = CTX_TYPE_DEFAULT;
115                                } else {
116                                        context = CTX_NONE;
117                                }
118                                if (isSet(FLG_TYPE_IS_NUMERIC)) {
119                                        if (isSet(FLG_MULTILINE) && !Character.isDigit(next())
120                                                        && next() != '-') {     // if default value is omitted
121                                                previous = aux_ENUM_LITERAL();
122                                                if (previous != null)
123                                                        return previous;
124                                        }
125                                        break;
126                                } else {
127                                        setState(RULE_HEADER_VALUE);
128                                        mRULE_TYPE_HEADER_VALUE();
129                                        return previous = emit();
130                                }
131                        } else if (context == CTX_TYPE_DEFAULT) {
132                                previous = aux_ENUM_LITERAL();
133                                if (previous != null)
134                                        return previous;
135                        }
136                        break;
137                case RULE_ID:
138                        if (context == CTX_TYPE) {
139                                if ("df".indexOf(previous.getText().charAt(0)) == -1) {
140                                        setFlag(FLG_TYPE_IS_NUMERIC, false);
141                                        setFlag(FLG_TYPE_IS_STRING, previous.getText().charAt(0) == (int)'s');
142                                } else {
143                                        setFlag(FLG_TYPE_IS_NUMERIC, true);
144                                }
145                                context = CTX_TYPE_ID;
146                                break;
147                        }
148                        context = CTX_NONE;
149                        break;
150                case RULE_HEADER_VALUE:
151                case RULE_ENUM_LITERAL:
152                        if (context == CTX_TYPE_DEFAULT) {
153                                previous = aux_ENUM_LITERAL();
154                                if (previous != null)
155                                        return previous;
156                        }
157                        context = CTX_NONE;
158                        break;
159                case RULE_DOUBLE:
160                case RULE_INT:
161                        if (context == CTX_TYPE_DEFAULT) {
162                                break;  // avoid changing context
163                        } else if (context == CTX_TYPE_ID) {
164                                context = CTX_TYPE_MIN;
165                                break;
166                        } else if (context == CTX_TYPE_MIN) {
167                                context = CTX_TYPE_MAX;
168                                break;
169                        }
170                        context = CTX_NONE;
171                        break;
172                default:
173                        if ("-".equals(previous.getText()) ||
174                                        "+".equals(previous.getText())) {
175                                break;
176                        }
177                        context = CTX_NONE;
178                case RULE_SL_COMMENT:
179                        break;
180                }
181                return previous = super.nextToken();
182        }
183
184        private boolean willMatch(String string) {
185                for (int i = 0; i < string.length(); ++i) {
186                        if (next(i+1) != string.charAt(i))
187                                return false;
188                }
189                return true;
190        }
191
192        private Token aux_ENUM_LITERAL() {
193                // CTX_TYPE_DEFAULT assumes raised FLG_MULTILINE
194                if (next() == '~') {
195                        setState(RULE_WS);      // any ignored token
196                        matchAny();
197                        context = CTX_NONE;
198                        return emit();
199                } else if (next() == '\\' && next(2) == '~') {
200                        matchAny();     // not assigned to any terminal
201                        setState(RULE_ENUM_LITERAL);
202                        matchAny();     // consume '~'
203                        mRULE_TYPE_HEADER_VALUE();
204                        return emit();
205                }
206                return null;
207        }
208       
209        private void mRULE_TYPE_HEADER_VALUE() {
210                if (isSet(FLG_MULTILINE)) {
211                        do {
212                                consumeUntilAny("\\~");
213                                if (next() == '\\' && next(2) != '~') {
214                                        matchAny();
215                                        continue;
216                                }
217                        } while (false);
218                } else {
219                        consumeUntilAny("~\r\n");
220                }
221        }
222
223        private void mHEADER_VALUE() {
224                if (isSet(FLG_MULTILINE)) {
225                        matchAny();     // consume '~'
226                        do {
227                                consumeUntilAny("\\~");
228                                if (next() == '\\') {
229                                        matchAny();
230                                        if (next() == '~')
231                                                matchAny();
232                                        continue;
233                                }
234                        } while (false);
235                        matchAny();
236                } else {
237                        consumeUntilAny("\r\n");
238                }
239        }
240}
Note: See TracBrowser for help on using the repository browser.