source: josm/trunk/src/org/openstreetmap/josm/tools/template_engine/TemplateParser.java@ 8811

Last change on this file since 8811 was 8811, checked in by simon04, 9 years ago

see #11916 - Refactoring of SearchAction/SearchCompiler

  • Property svn:eol-style set to native
File size: 5.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.tools.template_engine;
3
4
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.util.ArrayList;
8import java.util.Arrays;
9import java.util.Collection;
10import java.util.List;
11
12import org.openstreetmap.josm.actions.search.SearchCompiler;
13import org.openstreetmap.josm.actions.search.SearchCompiler.Match;
14import org.openstreetmap.josm.tools.template_engine.Tokenizer.Token;
15import org.openstreetmap.josm.tools.template_engine.Tokenizer.TokenType;
16
17
18public class TemplateParser {
19 private final Tokenizer tokenizer;
20
21 private static final Collection<TokenType> EXPRESSION_END_TOKENS = Arrays.asList(TokenType.EOF);
22 private static final Collection<TokenType> CONDITION_WITH_APOSTROPHES_END_TOKENS = Arrays.asList(TokenType.APOSTROPHE);
23
24 public TemplateParser(String template) {
25 this.tokenizer = new Tokenizer(template);
26 }
27
28 private Token check(TokenType expectedToken) throws ParseError {
29 Token token = tokenizer.nextToken();
30 if (token.getType() != expectedToken)
31 throw new ParseError(token, expectedToken);
32 else
33 return token;
34 }
35
36 public TemplateEntry parse() throws ParseError {
37 return parseExpression(EXPRESSION_END_TOKENS);
38 }
39
40 private TemplateEntry parseExpression(Collection<TokenType> endTokens) throws ParseError {
41 List<TemplateEntry> entries = new ArrayList<>();
42 while (true) {
43 TemplateEntry templateEntry;
44 Token token = tokenizer.lookAhead();
45 if (token.getType() == TokenType.CONDITION_START) {
46 templateEntry = parseCondition();
47 } else if (token.getType() == TokenType.CONTEXT_SWITCH_START) {
48 templateEntry = parseContextSwitch();
49 } else if (token.getType() == TokenType.VARIABLE_START) {
50 templateEntry = parseVariable();
51 } else if (endTokens.contains(token.getType()))
52 return CompoundTemplateEntry.fromArray(entries.toArray(new TemplateEntry[entries.size()]));
53 else if (token.getType() == TokenType.TEXT) {
54 tokenizer.nextToken();
55 templateEntry = new StaticText(token.getText());
56 } else
57 throw new ParseError(token);
58 entries.add(templateEntry);
59 }
60 }
61
62 private TemplateEntry parseVariable() throws ParseError {
63 check(TokenType.VARIABLE_START);
64 String variableName = check(TokenType.TEXT).getText();
65 check(TokenType.END);
66
67 return new Variable(variableName);
68 }
69
70 private void skipWhitespace() throws ParseError {
71 Token token = tokenizer.lookAhead();
72 if (token.getType() == TokenType.TEXT && token.getText().trim().isEmpty()) {
73 tokenizer.nextToken();
74 }
75 }
76
77 private TemplateEntry parseCondition() throws ParseError {
78 check(TokenType.CONDITION_START);
79 Condition result = new Condition();
80 while (true) {
81
82 TemplateEntry condition;
83 Token searchExpression = tokenizer.skip('\'');
84 check(TokenType.APOSTROPHE);
85 condition = parseExpression(CONDITION_WITH_APOSTROPHES_END_TOKENS);
86 check(TokenType.APOSTROPHE);
87 if (searchExpression.getText().trim().isEmpty()) {
88 result.getEntries().add(condition);
89 } else {
90 try {
91 result.getEntries().add(new SearchExpressionCondition(
92 SearchCompiler.compile(searchExpression.getText()), condition));
93 } catch (org.openstreetmap.josm.actions.search.SearchCompiler.ParseError e) {
94 throw new ParseError(searchExpression.getPosition(), e);
95 }
96 }
97 skipWhitespace();
98
99 Token token = tokenizer.lookAhead();
100 if (token.getType() == TokenType.END) {
101 tokenizer.nextToken();
102 return result;
103 } else {
104 check(TokenType.PIPE);
105 }
106 }
107 }
108
109 private TemplateEntry parseContextSwitch() throws ParseError {
110
111 check(TokenType.CONTEXT_SWITCH_START);
112 Token searchExpression = tokenizer.skip('\'');
113 check(TokenType.APOSTROPHE);
114 TemplateEntry template = parseExpression(CONDITION_WITH_APOSTROPHES_END_TOKENS);
115 check(TokenType.APOSTROPHE);
116 ContextSwitchTemplate result;
117 if (searchExpression.getText().trim().isEmpty())
118 throw new ParseError(tr("Expected search expression"));
119 else {
120 try {
121 Match match = SearchCompiler.compile(searchExpression.getText());
122 result = new ContextSwitchTemplate(match, template, searchExpression.getPosition());
123 } catch (org.openstreetmap.josm.actions.search.SearchCompiler.ParseError e) {
124 throw new ParseError(searchExpression.getPosition(), e);
125 }
126 }
127 skipWhitespace();
128 check(TokenType.END);
129 return result;
130 }
131
132}
Note: See TracBrowser for help on using the repository browser.