source: default/trunk/de.ugoe.cs.swe.bnftools.ebnf.ui/src/de/ugoe/cs/swe/bnftools/ui/actions/GenerateDeltaBnfAction.java

Last change on this file was 20, checked in by zeiss, 14 years ago
  • Property svn:mime-type set to text/plain
File size: 10.7 KB
Line 
1
2package de.ugoe.cs.swe.bnftools.ui.actions;
3
4
5import java.io.ByteArrayInputStream;
6import java.io.InputStream;
7import java.util.LinkedList;
8
9import org.eclipse.core.resources.IFile;
10import org.eclipse.core.resources.IResource;
11import org.eclipse.core.resources.ResourcesPlugin;
12import org.eclipse.core.runtime.CoreException;
13import org.eclipse.core.runtime.IPath;
14import org.eclipse.core.runtime.Path;
15import org.eclipse.emf.common.util.EList;
16import org.eclipse.emf.common.util.URI;
17import org.eclipse.emf.ecore.resource.Resource;
18import org.eclipse.jface.action.IAction;
19import org.eclipse.jface.dialogs.InputDialog;
20import org.eclipse.jface.viewers.ISelection;
21import org.eclipse.jface.viewers.IStructuredSelection;
22import org.eclipse.jface.viewers.StructuredSelection;
23import org.eclipse.jface.viewers.TreePath;
24import org.eclipse.jface.viewers.TreeSelection;
25import org.eclipse.ui.PlatformUI;
26import org.eclipse.ui.actions.ActionDelegate;
27import org.eclipse.xtext.parsetree.AbstractNode;
28import org.eclipse.xtext.parsetree.CompositeNode;
29import org.eclipse.xtext.parsetree.LeafNode;
30import org.eclipse.xtext.parsetree.NodeUtil;
31import org.eclipse.xtext.resource.XtextResource;
32import org.eclipse.xtext.resource.XtextResourceSet;
33
34import de.ugoe.cs.swe.bnftools.ebnf.Import;
35import de.ugoe.cs.swe.bnftools.ebnf.Rule;
36import de.ugoe.cs.swe.bnftools.ebnf.SectionHeading;
37
38public class GenerateDeltaBnfAction extends ActionDelegate {
39        private IStructuredSelection selection = StructuredSelection.EMPTY;
40        private IFile file=null;
41       
42        @Override
43        public void run(IAction action) {
44                TreeSelection treeSelection = (TreeSelection) selection;
45                TreePath[] paths = treeSelection.getPaths();
46
47                for (int i = 0; i < paths.length; i++) {
48                        TreePath path = paths[i];
49                        IFile f = (IFile) path.getLastSegment();
50                        XtextResourceSet set = new XtextResourceSet();
51                        String fp = f.getFullPath().toString();
52                        URI uri = URI.createPlatformResourceURI(fp,true);
53                       
54                        Resource resource = set.getResource(uri, true);
55                        if (resource instanceof XtextResource) {
56                               
57                                XtextResource xtextResource = (XtextResource) resource;
58                                               
59                                /*
60                                 * Creating a delta grammar outline:
61                                 * 1. Get the core grammar
62                                 *              1.1 - get all imports
63                                 *              1.2 - if number of imports != 1, break
64                                 *              1.3 - get the grammar corresponding to the only import
65                                 * 2. Run through all rules in the package
66                                 *              2.1 for each rule, run through all rules in the core
67                                 *              2.2 if any rule has the same name, convert to delta form
68                                 *              2.3 copy all package only rules in the delta grammar
69                                 */
70                                CompositeNode compNode = xtextResource.getParseResult().getRootNode();
71                                Iterable<AbstractNode> allNodes = NodeUtil.getAllContents(compNode);
72                       
73                                int count = 0;
74                                Resource coreRes = null;
75                                LinkedList<XtextResource> imports = new LinkedList<XtextResource>();
76                                for (AbstractNode node : allNodes) {
77                                       
78                                        if(count >=2)
79                                                return;
80                                       
81                                        if(node.getElement() instanceof Import) {
82                                                String packageUri = uri.trimSegments(1).toPlatformString(true);
83                                                String fullUri = packageUri + "/" +((Import) node.getElement()).getImportURI();
84                                                URI uri2 = URI.createPlatformResourceURI(fullUri, true);
85                                                Resource tempRes = set.getResource(uri2, true);
86                                                if(tempRes instanceof XtextResource) {
87                                                        if(((Import) node.getElement()).getGrammarType()!=null && ((Import) node.getElement()).getGrammarType().equals("core")) {
88                                                        count++;
89                                                        coreRes=tempRes;
90                                                        }
91                                                       
92                                                        else
93                                                                imports.add((XtextResource) tempRes);
94                                                               
95                                                }
96                                        }
97
98                                }
99                                       
100//                              if(count!=1)
101//                                      return;         
102//                     
103                                if ((coreRes == null)&&(imports.size()==1))
104                                                coreRes = imports.get(0);
105                                //create a new file in the root folder of the current project that stores the delta grammar
106                                InputDialog di = new InputDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Name Selection",
107                                                "Please type a name for the delta grammar.", uri.trimFileExtension().segment(uri.segmentCount()-1) + "_delta.bnf", null);
108                                di.open();
109                               
110                                if (di.getReturnCode() == InputDialog.CANCEL)
111                                        return;
112                               
113                                String fname = di.getValue();
114                               
115                                String loc = uri.trimFileExtension().trimSegments(1).toPlatformString(true);
116                                loc = loc.concat("/" + fname);
117                                IPath filePath = new Path(loc);
118                                file = ResourcesPlugin.getWorkspace().getRoot().getFile(filePath);
119                                   
120                                   try {
121                                   if (!file.exists()) {
122                                      byte[] bytes = ("//Automatically generated merge grammar from: " + uri.trimFileExtension().segment(uri.segmentCount()-1) + '\n').getBytes();
123                                      InputStream source = new ByteArrayInputStream(bytes);
124                                      file.create(source, IResource.NONE, null);                                     
125                                   }
126                                   else return;
127                                        } catch (CoreException e) {
128                                                e.printStackTrace();
129                                        }
130                                createNewLine("/delta;" + '\n');
131                                       
132                                boolean newRule = true;
133                                       
134                                for(AbstractNode node : allNodes) {
135                                        newRule=true;
136                                       
137                                        if(node.getElement() instanceof Rule){
138                                               
139                                                newRule = checkForExtensions(node, (XtextResource) coreRes);
140
141                                               
142                                                if(newRule) {
143                                                        for(int j=0; j<imports.size(); j++) {
144                                                                if(!newRule)
145                                                                        break;
146                                                                newRule=checkForExtensions(node, imports.get(i));
147                                                        }
148                                                }
149                                               
150                                        }
151                                        if(node.getElement() instanceof Import)
152                                                createNewLine(node.serialize().trim()  + '\n');
153                                       
154                                        if((newRule)&&((node.getElement() instanceof Rule)
155                                                        ||(node.getElement() instanceof SectionHeading)))
156                                                createNewLine(node.serialize());
157                                }
158                       
159                        }
160       
161                }
162        }
163
164
165        private boolean checkForExtensions(AbstractNode node, XtextResource xtextResource) {
166               
167                if(node.getElement() instanceof Rule) {
168                        Rule rule1 = (Rule) node.getElement();
169               
170                        for(AbstractNode node2 : NodeUtil.getAllContents(((XtextResource) xtextResource).getParseResult().getRootNode())) {
171                       
172                                if(node2.getElement() instanceof Rule) {
173                                        Rule rule2 = (Rule) node2.getElement();
174                               
175                                if(rule1.getName().equals(rule2.getName())) {
176                                        splitRule(node2, node );
177                                        return false;
178                                       
179                                        }
180                               
181                                }
182                       
183                        }
184                }
185                return true;
186        }
187        /*
188         * Given 2 rules with the same name, the 2nd of which extends the 1st,
189         * create a new extension rule for every part of the package rule not in
190         * the core rule:
191         *
192         *      1. get all the leaf nodes of each rule (the basic grammar elements)
193         *      2. check all the leaves in both rules in the order they occur so that:
194         *              2.1 if one leaf is whitespace, continue
195         *              2.2 else, check for equality:
196         *                      2.2.1 if both are equal, continue,
197         *                      2.2.2 else, if the node from the package is a bracket, remember the bracket and
198         * wait for the next closing bracket of the same kind. Add all between those brackets to the current extension
199         *                      2.2.3 else, add the current node from the package to the current extension
200         *                      2.2.4 when equality occurs, create a new rule in the delta grammar with the current extension string
201         */
202        private void splitRule(AbstractNode cNode, AbstractNode pNode) {
203               
204                EList<LeafNode> cLeaves = cNode.getLeafNodes();
205                EList<LeafNode> pLeaves = pNode.getLeafNodes();
206               
207                int c=0; //counter for cLeaves.size()
208                int p=0;
209               
210                int offset=0; //counter for the offset in the core grammar in the extension,
211                //given in number of leaf nodes, excluding whitespaces
212                boolean bracket1 = false; // ()
213                boolean bracket2 = false; //[]
214                boolean bracket3 = false; //{}
215               
216                boolean last = false;
217                String temp = "";
218                String temp1 = "";
219               
220                boolean rightSide=true;
221                boolean rightSide2=true;
222               
223                while((p < pLeaves.size())){
224                       
225                        if(rightSide) {
226                                if(cLeaves.get(c).serialize().equals("::="))
227                                        rightSide=false;
228                                else if(!(cLeaves.get(c).getGrammarElement() instanceof org.eclipse.xtext.impl.TerminalRuleImpl))
229                                        temp1=temp1.concat(cLeaves.get(c).serialize());
230                                c++;
231                                continue;
232                        }
233                       
234                        if(rightSide2) {
235                                if(pLeaves.get(p).serialize().equals("::="))
236                                        rightSide2=false;
237                                p++;
238                                continue;
239                        }
240                       
241                        if(c == cLeaves.size()) {
242                                if(!(pLeaves.get(p).getGrammarElement() instanceof org.eclipse.xtext.impl.TerminalRuleImpl))
243                                temp=temp.concat(pLeaves.get(p).serialize());
244                                p++;
245                                if(pLeaves.size()==p) {
246                                        createNewLine( '\n' + temp1 + "(" + offset + ") <- " + temp );
247                                        return;
248                                }
249                                continue;
250                        }
251                       
252                        if((cLeaves.get(c).getGrammarElement() instanceof org.eclipse.xtext.impl.TerminalRuleImpl)) {
253                                c++;
254                                continue;
255                        }
256                       
257                        if((pLeaves.get(p).getGrammarElement() instanceof org.eclipse.xtext.impl.TerminalRuleImpl)) {
258                                p++;
259                                continue;
260                        }
261
262                       
263                        if(bracket1) {
264                                if(pLeaves.get(p).serialize().equals(")")) {
265                                        bracket1=false;
266                                        p++;
267                                        last=true;
268                                        temp=temp.concat(") ");
269                                        continue;
270                                }
271                                //wait for bracket1
272                        }
273                       
274                        if(bracket2) {
275                                if(pLeaves.get(p).serialize().equals("]")) {
276                                        bracket2=false;
277                                        p++;
278                                        last=true;
279                                        temp=temp.concat("] ");
280                                        continue;
281                                }
282                                //wait for bracket2
283                        }
284                       
285                        if(bracket3) {
286                                if(pLeaves.get(p).serialize().equals("}")) {
287                                        bracket3=false;
288                                        p++;
289                                        last=true;
290                                        temp=temp.concat("} ");
291                                        continue;
292                                }
293                                //wait for bracket3
294                        }
295                       
296//                      else {
297                                if(last) {
298                                        //check if its the end of the extension
299                                        if(pLeaves.get(p).serialize().equals(cLeaves.get(c).serialize())){
300                                                last=false;
301                                                createNewLine( '\n' + temp1 + "(" + offset + ") <- " + temp );
302                                                temp="";
303                                                c++;
304                                                p++;
305                                                offset++;
306                                                continue;
307                                        }
308                                }
309                               
310                                if(pLeaves.get(p).serialize().equals(cLeaves.get(c).serialize())){
311                                        c++;
312                                        p++;
313                                        offset++;
314                                        continue;
315                                }
316                               
317                                last=true;
318                               
319                               
320                                String temp2=pLeaves.get(p).serialize();
321                                if(temp2.equals("("))
322                                        bracket1=true;
323                                if(temp2.equals("["))
324                                        bracket2=true;
325                                if(temp2.equals("{"))
326                                        bracket3=true;
327                                       
328                                temp=temp.concat(temp2);
329                                p++;
330                        }
331                       
332//              }
333        }
334       
335        /*
336         * Algorithm for creating a new Ext Rule, given name, point and text
337         * 1. allocate a new line for the rule
338         * 2. write the given input in there
339         */
340        private void createNewLine(String rule) {
341                try {
342                           if (file.exists()) {
343                              byte[] bytes = (rule).getBytes();
344                              InputStream source = new ByteArrayInputStream(bytes);
345                              file.appendContents(source, IResource.NONE, null);
346                           }
347                                } catch (CoreException e) {
348                                        e.printStackTrace();
349                        }
350        }
351        @Override
352        public void selectionChanged(IAction action, ISelection selection) {
353                if (selection instanceof IStructuredSelection) {
354                        this.selection = (IStructuredSelection) selection;
355                } else {
356                        this.selection = StructuredSelection.EMPTY;
357                }
358        }
359}
Note: See TracBrowser for help on using the repository browser.