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

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