source: default/trunk/de.ugoe.cs.swe.bnftools.ebnf.ui/src/de/ugoe/cs/swe/bnftools/ui/formatter/EbnfFormatterVisitor.java @ 21

Last change on this file since 21 was 21, checked in by zeiss, 14 years ago
  • Property svn:mime-type set to text/plain
File size: 11.1 KB
Line 
1package de.ugoe.cs.swe.bnftools.ui.formatter;
2
3import java.util.ArrayList;
4
5import org.eclipse.emf.common.util.EList;
6import org.eclipse.emf.ecore.EObject;
7import org.eclipse.xtext.parsetree.AbstractNode;
8import org.eclipse.xtext.parsetree.CompositeNode;
9import org.eclipse.xtext.parsetree.LeafNode;
10import org.eclipse.xtext.parsetree.NodeAdapter;
11import org.eclipse.xtext.parsetree.NodeUtil;
12
13import de.ugoe.cs.swe.bnftools.ebnf.Atom;
14import de.ugoe.cs.swe.bnftools.ebnf.BnfEntry;
15import de.ugoe.cs.swe.bnftools.ebnf.DefinitionList;
16import de.ugoe.cs.swe.bnftools.ebnf.DeltaEntry;
17import de.ugoe.cs.swe.bnftools.ebnf.EtsiBnf;
18import de.ugoe.cs.swe.bnftools.ebnf.ExtRule;
19import de.ugoe.cs.swe.bnftools.ebnf.GlobalCombinator;
20import de.ugoe.cs.swe.bnftools.ebnf.GroupedSequence;
21import de.ugoe.cs.swe.bnftools.ebnf.HookCombinator;
22import de.ugoe.cs.swe.bnftools.ebnf.Import;
23import de.ugoe.cs.swe.bnftools.ebnf.ImportSection;
24import de.ugoe.cs.swe.bnftools.ebnf.MergeEntry;
25import de.ugoe.cs.swe.bnftools.ebnf.MergeRule;
26import de.ugoe.cs.swe.bnftools.ebnf.OptionalSequence;
27import de.ugoe.cs.swe.bnftools.ebnf.RepeatedSequence;
28import de.ugoe.cs.swe.bnftools.ebnf.Rule;
29import de.ugoe.cs.swe.bnftools.ebnf.RuleCombinator;
30import de.ugoe.cs.swe.bnftools.ebnf.RuleReference;
31import de.ugoe.cs.swe.bnftools.ebnf.SectionHeading;
32import de.ugoe.cs.swe.bnftools.ebnf.SingleDefinition;
33import de.ugoe.cs.swe.bnftools.ebnf.StringRule;
34import de.ugoe.cs.swe.bnftools.ebnf.Term;
35import de.ugoe.cs.swe.bnftools.visitor.EbnfVisitor;
36
37public class EbnfFormatterVisitor extends EbnfVisitor {
38        private StringBuffer buf;
39        private FormatterConfig config;
40        private int bufferPosition = 0;
41        private int bufferPositionOriginalText = 0;
42        private int commentPosition = 0;
43        private int allCommentsPosition = 0;
44        private ArrayList<LeafNode> allComments = new ArrayList<LeafNode>();
45        private ArrayList<String> collectedComments = new ArrayList<String>();
46       
47        private boolean lastWasSectionHeading=false;
48        private CompositeNode parserEtsiBnfNode;
49        private String originalText;
50        private String originalTextNoWhitespaces;
51        private int bufferPositionFormattedText;
52        private String formattedText;
53        private String bufNoWhitespaces;
54       
55        public EbnfFormatterVisitor(EObject rootNode, FormatterConfig config) {
56                super(rootNode);
57                this.config = config;
58                buf = new StringBuffer();
59        }
60
61        public EbnfFormatterVisitor(FormatterConfig config) {
62                this.config = config;
63                buf = new StringBuffer();
64        }
65
66        public StringBuffer getBuf() {
67                return buf;
68        }
69
70        private boolean isCommentNode(LeafNode node) {
71                if ((node.getText().trim().startsWith("//") || node.getText().trim().startsWith("/*")) && (node.isHidden()))
72                        return true;
73                return false;
74        }
75       
76        private void collectAllComments(CompositeNode node) {
77                for (int i=0; i < node.getChildren().size(); i++) {
78                        AbstractNode currentNode = node.getChildren().get(i);
79                        if (currentNode instanceof LeafNode) {
80                                LeafNode leafNode = (LeafNode) currentNode;
81                                if (isCommentNode(leafNode)) {
82                                        allComments.add(leafNode);
83                                }
84                        }
85                       
86                        if (currentNode instanceof CompositeNode) {
87                                collectAllComments((CompositeNode) currentNode);
88                        }
89                }
90        }
91
92//      private ArrayList<String> collectComments(CompositeNode node) {
93//              collectedComments.clear();
94////            System.out.println(node);
95////            System.out.println(node.serialize());
96////            searchSubTree(node);
97//              return collectedComments;
98//      }
99       
100        private boolean isSingleLineComment(String str) {
101                if (str.startsWith("//"))
102                        return true;
103                return false;
104        }
105       
106        private boolean isMultiLineComment(String str) {
107                if (str.startsWith("/*"))
108                        return true;
109                return false;
110        }
111
112        private boolean isWhitespace(char ch) {
113                if ((ch==' ') || (ch == '\t') || (ch == '\n') || (ch == '\r'))
114                        return true;
115                return false;
116        }
117       
118        private void skipWhitespacesOriginalText() {
119                while (isWhitespace(originalText.charAt(bufferPositionOriginalText))) {
120                        bufferPositionOriginalText++;
121                }
122        }
123
124        private void skipWhitespacesFormattedText(StringBuffer result) {
125                while (isWhitespace(formattedText.charAt(bufferPositionFormattedText))) {
126                        result.append(formattedText.substring(bufferPositionFormattedText, bufferPositionFormattedText+1));
127                        bufferPositionFormattedText++;
128                }
129        }
130
131        private boolean isSingleLineCommentNext(String str, int position) {
132                if ((str.charAt(position) == '/') && (str.charAt(position) == '/'))
133                        return true;
134                return false;
135        }
136       
137        private boolean isMultiLineCommentNext(String str, int position) {
138                if ((str.charAt(position) == '/') && (str.charAt(position) == '*'))
139                        return true;
140                return false;
141        }
142               
143        private boolean isCommentNext(String str, int position) {
144                if (isSingleLineCommentNext(str, position) || isMultiLineCommentNext(str, position))
145                        return true;
146                else
147                        return false;
148        }
149       
150        private void weaveComments() {
151                bufferPosition = 0;
152                bufferPositionOriginalText = 0;
153                bufferPositionFormattedText = 0;
154               
155                StringBuffer result = new StringBuffer();
156                bufNoWhitespaces = buf.toString().replaceAll("[ \t\n\r]", "");
157                formattedText = buf.toString();
158               
159                while (bufferPosition < bufNoWhitespaces.length()) {
160                        skipWhitespacesOriginalText();
161                        skipWhitespacesFormattedText(result);
162
163                        if (bufNoWhitespaces.charAt(bufferPosition) != originalText.charAt(bufferPositionOriginalText)) {
164                                if (isCommentNext(originalText, bufferPositionOriginalText)) {
165                                        LeafNode currentComment = allComments.get(allCommentsPosition);
166                                        if (currentComment.getTotalOffset() == bufferPositionOriginalText) {
167                                                result.append(currentComment.getText());
168                                               
169                                                if (isMultiLineComment(currentComment.getText())) {
170                                                        result.append("\n");
171                                                }
172                                                bufferPositionOriginalText+=currentComment.getLength();
173                                                allCommentsPosition++;
174                                        }
175                                }
176                               
177                        } else {
178                                result.append(formattedText.substring(bufferPositionFormattedText, bufferPositionFormattedText+1));
179
180                                bufferPositionOriginalText++;
181                                bufferPositionFormattedText++;
182                                bufferPosition++;
183                        }
184                }
185                buf = result;
186               
187        }
188       
189        private void appendComments(EObject node) {
190//              String currentBuf = buf.toString().replaceAll("[ \t\n\r]", "");
191//              while (bufferPosition < currentBuf.length()) {
192//                      skipWhitespacesOriginalText();
193//                      System.out.print(currentBuf.charAt(bufferPosition));
194//                      System.out.print(originalText.charAt(bufferPositionOriginalText));
195//                      bufferPositionOriginalText++;
196//                      bufferPosition++;
197//              }
198               
199//
200//              ArrayList<String> comments = collectComments(parseTreeNode);
201//              for (int i=0; i < comments.size(); i++) {
202//                      if (isSingleLineComment(comments.get(i))) {
203//                              buf.append(" ");
204//                              buf.append(comments.get(i).trim());
205//                              if (i+1 < comments.size())
206//                                      buf.append("\n");
207//                      } else if (isMultiLineComment(comments.get(i))) {
208//                              buf.append("\n");
209//                              buf.append(comments.get(i));
210//                              if (i+1 < comments.size())
211//                                      buf.append("\n");
212//                      }
213//              }
214               
215        }
216       
217        // -----------------------------------------------------------------------------
218
219        protected void visitBefore(EtsiBnf node) {
220                parserEtsiBnfNode = NodeUtil.getNodeAdapter(node).getParserNode();
221                collectAllComments(parserEtsiBnfNode);
222                originalText = NodeUtil.getNodeAdapter(node).getParserNode().serialize();
223                originalTextNoWhitespaces = originalText.replaceAll("[ \t\n\r]", "");
224               
225                //System.out.println(allComments.toString());
226                buf.append("grammar " + node.getName());
227                if (node.getType() != null)
228                        buf.append(node.getType());
229                buf.append(";");
230
231                appendComments(node);
232               
233                buf.append("\n\n");
234        }
235
236        protected void visitAfter(EtsiBnf node) {
237                weaveComments();
238        }
239
240        protected void visitBefore(ImportSection node) {
241        }
242
243        protected void visitAfter(ImportSection node) {
244                buf.append("\n");
245        }
246
247        protected void visitBefore(BnfEntry node) {
248        }
249
250        protected void visitAfter(BnfEntry node) {
251        }
252       
253        protected void visitBefore(DeltaEntry node) {
254        }
255
256        protected void visitAfter(DeltaEntry node) {
257        }
258       
259        protected void visitBefore(MergeEntry node) {
260        }
261
262        protected void visitAfter(MergeEntry node) {
263        }
264       
265        protected void visitBefore(Atom node) {
266        }
267
268        protected void visitAfter(Atom node) {
269        }
270
271        protected void visitBefore(Term node) {
272        }
273
274        protected void visitAfter(Term node) {
275                if (!isLastElement())
276                        buf.append(" ");
277        }
278
279        protected void visitBefore(DefinitionList node) {
280        }
281
282        protected void visitAfter(DefinitionList node) {
283        }
284
285        protected void visitBefore(ExtRule node) {
286        }
287
288        protected void visitAfter(ExtRule node) {
289        }
290
291        protected void visitBefore(GlobalCombinator node) {
292        }
293
294        protected void visitAfter(GlobalCombinator node) {
295        }
296
297        protected void visitBefore(GroupedSequence node) {
298                buf.append("(");
299        }
300
301        protected void visitAfter(GroupedSequence node) {
302                buf.append(")");
303        }
304
305        protected void visitBefore(HookCombinator node) {
306        }
307
308        protected void visitAfter(HookCombinator node) {
309        }
310
311        protected void visitBefore(Import node) {
312                buf.append("import \"" + node.getImportURI() + "\";");
313                appendComments(node);
314                buf.append("\n");
315               
316        }
317
318        protected void visitAfter(Import node) {
319        }
320
321        protected void visitBefore(MergeRule node) {
322        }
323
324        protected void visitAfter(MergeRule node) {
325        }
326
327        protected void visitBefore(OptionalSequence node) {
328                buf.append("[");
329        }
330
331        protected void visitAfter(OptionalSequence node) {
332                buf.append("]");
333        }
334
335        protected void visitBefore(RepeatedSequence node) {
336                buf.append("{");
337        }
338
339        protected void visitAfter(RepeatedSequence node) {
340                buf.append("}");
341                if (node.isMorethanonce())
342                        buf.append("+");
343        }
344
345        protected void visitBefore(Rule node) {
346                if (lastWasSectionHeading)
347                        buf.append("\n");
348               
349                lastWasSectionHeading=false;
350
351                if (node.getRulenumber() > 0)
352                        buf.append(node.getRulenumber() + ". ");
353               
354                buf.append(node.getName() + " ::= ");
355        }
356
357        protected void visitAfter(Rule node) {
358                buf.append(";");
359//              appendComments(node);
360                buf.append("\n");
361        }
362
363        protected void visitBefore(RuleCombinator node) {
364        }
365
366        protected void visitAfter(RuleCombinator node) {
367        }
368
369        protected void visitBefore(RuleReference node) {
370                buf.append(node.getRuleref().getName());
371        }
372
373        protected void visitAfter(RuleReference node) {
374        }
375
376        protected void visitBefore(SectionHeading node) {
377                if (!lastWasSectionHeading && !buf.substring(buf.length()-2).equals("\n\n"))
378                        buf.append("\n");
379               
380                lastWasSectionHeading=true;
381//              if (!lastWasSectionHeading || !buf.substring(buf.length()-2).equals("\n\n"))
382//              if (!buf.substring(buf.length()-2).equals("\n\n"))
383//                      buf.append("\n");
384               
385                buf.append(node.getSectionHeader());
386               
387                appendComments(node);
388        }
389
390        protected void visitAfter(SectionHeading node) {
391//              buf.append("\n");
392        }
393
394        protected void visitBefore(SingleDefinition node) {
395        }
396
397        protected void visitAfter(SingleDefinition node) {
398                if (!isLastElement())
399                        buf.append(" | ");
400               
401        }
402
403        protected void visitBefore(StringRule node) {
404                if (node.getLiteral() != null)
405                        buf.append("\"" + node.getLiteral() + "\"");
406                else if (node.getColon() != null)
407                        buf.append("\"\"\"");
408        }
409
410        protected void visitAfter(StringRule node) {
411        }
412
413       
414       
415}
Note: See TracBrowser for help on using the repository browser.