package de.ugoe.cs.swe.bnftools.ui.actions; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.LinkedList; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.ActionDelegate; import org.eclipse.xtext.parsetree.AbstractNode; import org.eclipse.xtext.parsetree.CompositeNode; import org.eclipse.xtext.parsetree.LeafNode; import org.eclipse.xtext.parsetree.NodeUtil; import org.eclipse.xtext.resource.XtextResource; import org.eclipse.xtext.resource.XtextResourceSet; import de.ugoe.cs.swe.bnftools.ebnf.Import; import de.ugoe.cs.swe.bnftools.ebnf.Rule; import de.ugoe.cs.swe.bnftools.ebnf.SectionHeading; public class GenerateDeltaBnfAction extends ActionDelegate { private IStructuredSelection selection = StructuredSelection.EMPTY; private IFile file=null; @Override public void run(IAction action) { TreeSelection treeSelection = (TreeSelection) selection; TreePath[] paths = treeSelection.getPaths(); for (int i = 0; i < paths.length; i++) { TreePath path = paths[i]; IFile f = (IFile) path.getLastSegment(); XtextResourceSet set = new XtextResourceSet(); String fp = f.getFullPath().toString(); URI uri = URI.createPlatformResourceURI(fp,true); Resource resource = set.getResource(uri, true); if (resource instanceof XtextResource) { XtextResource xtextResource = (XtextResource) resource; /* * Creating a delta grammar outline: * 1. Get the core grammar * 1.1 - get all imports * 1.2 - if number of imports != 1, break * 1.3 - get the grammar corresponding to the only import * 2. Run through all rules in the package * 2.1 for each rule, run through all rules in the core * 2.2 if any rule has the same name, convert to delta form * 2.3 copy all package only rules in the delta grammar */ CompositeNode compNode = xtextResource.getParseResult().getRootNode(); Iterable allNodes = NodeUtil.getAllContents(compNode); int count = 0; Resource coreRes = null; LinkedList imports = new LinkedList(); for (AbstractNode node : allNodes) { if(count >=2) return; if(node.getElement() instanceof Import) { String packageUri = uri.trimSegments(1).toPlatformString(true); String fullUri = packageUri + "/" +((Import) node.getElement()).getImportURI(); URI uri2 = URI.createPlatformResourceURI(fullUri, true); Resource tempRes = set.getResource(uri2, true); if(tempRes instanceof XtextResource) { if(((Import) node.getElement()).getGrammarType()!=null && ((Import) node.getElement()).getGrammarType().equals("core")) { count++; coreRes=tempRes; } else imports.add((XtextResource) tempRes); } } } // if(count!=1) // return; // if ((coreRes == null)&&(imports.size()==1)) coreRes = imports.get(0); //create a new file in the root folder of the current project that stores the delta grammar InputDialog di = new InputDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Name Selection", "Please type a name for the delta grammar.", uri.trimFileExtension().segment(uri.segmentCount()-1) + "_delta.bnf", null); di.open(); if (di.getReturnCode() == InputDialog.CANCEL) return; String fname = di.getValue(); String loc = uri.trimFileExtension().trimSegments(1).toPlatformString(true); loc = loc.concat("/" + fname); IPath filePath = new Path(loc); file = ResourcesPlugin.getWorkspace().getRoot().getFile(filePath); try { if (!file.exists()) { byte[] bytes = ("//Automatically generated merge grammar from: " + uri.trimFileExtension().segment(uri.segmentCount()-1) + '\n').getBytes(); InputStream source = new ByteArrayInputStream(bytes); file.create(source, IResource.NONE, null); } else return; } catch (CoreException e) { e.printStackTrace(); } createNewLine("/delta;" + '\n'); boolean newRule = true; for(AbstractNode node : allNodes) { newRule=true; if(node.getElement() instanceof Rule){ newRule = checkForExtensions(node, (XtextResource) coreRes); if(newRule) { for(int j=0; j cLeaves = cNode.getLeafNodes(); EList pLeaves = pNode.getLeafNodes(); int c=0; //counter for cLeaves.size() int p=0; int offset=0; //counter for the offset in the core grammar in the extension, //given in number of leaf nodes, excluding whitespaces boolean bracket1 = false; // () boolean bracket2 = false; //[] boolean bracket3 = false; //{} boolean last = false; String temp = ""; String temp1 = ""; boolean rightSide=true; boolean rightSide2=true; while((p < pLeaves.size())){ if(rightSide) { if(cLeaves.get(c).serialize().equals("::=")) rightSide=false; else if(!(cLeaves.get(c).getGrammarElement() instanceof org.eclipse.xtext.impl.TerminalRuleImpl)) temp1=temp1.concat(cLeaves.get(c).serialize()); c++; continue; } if(rightSide2) { if(pLeaves.get(p).serialize().equals("::=")) rightSide2=false; p++; continue; } if(c == cLeaves.size()) { if(!(pLeaves.get(p).getGrammarElement() instanceof org.eclipse.xtext.impl.TerminalRuleImpl)) temp=temp.concat(pLeaves.get(p).serialize()); p++; if(pLeaves.size()==p) { createNewLine( '\n' + temp1 + "(" + offset + ") <- " + temp ); return; } continue; } if((cLeaves.get(c).getGrammarElement() instanceof org.eclipse.xtext.impl.TerminalRuleImpl)) { c++; continue; } if((pLeaves.get(p).getGrammarElement() instanceof org.eclipse.xtext.impl.TerminalRuleImpl)) { p++; continue; } if(bracket1) { if(pLeaves.get(p).serialize().equals(")")) { bracket1=false; p++; last=true; temp=temp.concat(") "); continue; } //wait for bracket1 } if(bracket2) { if(pLeaves.get(p).serialize().equals("]")) { bracket2=false; p++; last=true; temp=temp.concat("] "); continue; } //wait for bracket2 } if(bracket3) { if(pLeaves.get(p).serialize().equals("}")) { bracket3=false; p++; last=true; temp=temp.concat("} "); continue; } //wait for bracket3 } // else { if(last) { //check if its the end of the extension if(pLeaves.get(p).serialize().equals(cLeaves.get(c).serialize())){ last=false; createNewLine( '\n' + temp1 + "(" + offset + ") <- " + temp ); temp=""; c++; p++; offset++; continue; } } if(pLeaves.get(p).serialize().equals(cLeaves.get(c).serialize())){ c++; p++; offset++; continue; } last=true; String temp2=pLeaves.get(p).serialize(); if(temp2.equals("(")) bracket1=true; if(temp2.equals("[")) bracket2=true; if(temp2.equals("{")) bracket3=true; temp=temp.concat(temp2); p++; } // } } /* * Algorithm for creating a new Ext Rule, given name, point and text * 1. allocate a new line for the rule * 2. write the given input in there */ private void createNewLine(String rule) { try { if (file.exists()) { byte[] bytes = (rule).getBytes(); InputStream source = new ByteArrayInputStream(bytes); file.appendContents(source, IResource.NONE, null); } } catch (CoreException e) { e.printStackTrace(); } } @Override public void selectionChanged(IAction action, ISelection selection) { if (selection instanceof IStructuredSelection) { this.selection = (IStructuredSelection) selection; } else { this.selection = StructuredSelection.EMPTY; } } }