source: josm/trunk/src/org/openstreetmap/josm/tools/template_engine/Tokenizer.java@ 4548

Last change on this file since 4548 was 4548, checked in by jttt, 12 years ago

Fix name template parser

File size: 3.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.tools.template_engine;
3
4import java.util.Arrays;
5import java.util.List;
6
7public class Tokenizer {
8
9 public static class Token {
10 private final TokenType type;
11 private final int position;
12 private final String text;
13
14 public Token(TokenType type, int position) {
15 this(type, position, null);
16 }
17
18 public Token(TokenType type, int position, String text) {
19 this.type = type;
20 this.position = position;
21 this.text = text;
22 }
23
24 public TokenType getType() {
25 return type;
26 }
27
28 public int getPosition() {
29 return position;
30 }
31
32 public String getText() {
33 return text;
34 }
35
36 @Override
37 public String toString() {
38 return type + (text != null?" " + text:"");
39 }
40 }
41
42 public enum TokenType { CONDITION_START, VARIABLE_START, CONTEXT_SWITCH_START, END, PIPE, APOSTROPHE, TEXT, EOF }
43
44 private final List<Character> specialCharaters = Arrays.asList(new Character[] {'$', '?', '{', '}', '|', '\'', '!'});
45
46 private final String template;
47
48 private int c;
49 private int index;
50 private Token currentToken;
51 private StringBuilder text = new StringBuilder();
52
53 public Tokenizer(String template) {
54 this.template = template;
55 getChar();
56 }
57
58 private void getChar() {
59 if (index >= template.length()) {
60 c = -1;
61 } else {
62 c = template.charAt(index++);
63 }
64 }
65
66 public Token nextToken() throws ParseError {
67 if (currentToken != null) {
68 Token result = currentToken;
69 currentToken = null;
70 return result;
71 }
72 int position = index;
73
74 text.setLength(0);
75 switch (c) {
76 case -1:
77 return new Token(TokenType.EOF, position);
78 case '{':
79 getChar();
80 return new Token(TokenType.VARIABLE_START, position);
81 case '?':
82 getChar();
83 if (c == '{') {
84 getChar();
85 return new Token(TokenType.CONDITION_START, position);
86 } else
87 throw ParseError.unexpectedChar('{', (char)c, position);
88 case '!':
89 getChar();
90 if (c == '{') {
91 getChar();
92 return new Token(TokenType.CONTEXT_SWITCH_START, position);
93 } else
94 throw ParseError.unexpectedChar('{', (char)c, position);
95 case '}':
96 getChar();
97 return new Token(TokenType.END, position);
98 case '|':
99 getChar();
100 return new Token(TokenType.PIPE, position);
101 case '\'':
102 getChar();
103 return new Token(TokenType.APOSTROPHE, position);
104 default:
105 while (c != -1 && !specialCharaters.contains((char)c)) {
106 if (c == '\\') {
107 getChar();
108 if (c == 'n') {
109 c = '\n';
110 }
111 }
112 text.append((char)c);
113 getChar();
114 }
115 return new Token(TokenType.TEXT, position, text.toString());
116 }
117 }
118
119 public Token lookAhead() throws ParseError {
120 if (currentToken == null) {
121 currentToken = nextToken();
122 }
123 return currentToken;
124 }
125
126 public Token skip(char lastChar) {
127 currentToken = null;
128 int position = index;
129 StringBuilder result = new StringBuilder();
130 while (c != lastChar && c != -1) {
131 if (c == '\\') {
132 getChar();
133 }
134 result.append((char)c);
135 getChar();
136 }
137 return new Token(TokenType.TEXT, position, result.toString());
138 }
139
140}
Note: See TracBrowser for help on using the repository browser.