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.ExtRule; import de.ugoe.cs.swe.bnftools.ebnf.GlobalCombinator; import de.ugoe.cs.swe.bnftools.ebnf.HookCombinator; import de.ugoe.cs.swe.bnftools.ebnf.Import; import de.ugoe.cs.swe.bnftools.ebnf.Rule; import de.ugoe.cs.swe.bnftools.ebnf.RuleCombinator; import de.ugoe.cs.swe.bnftools.ebnf.impl.EtsiBnfImpl; public class GenerateCompositeBNFAction extends ActionDelegate{ private IStructuredSelection selection = StructuredSelection.EMPTY; private IFile file=null; private XtextResource coreGrammar=null; private LinkedList packageGrammars; private XtextResource xtextResource; private LinkedList deltas; private String global=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) resource; if(!((EtsiBnfImpl) xtextResource.getParseResult().getRootNode().getElement()).getType().equals("/merge")) continue; InputDialog di = new InputDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Name Selection", "Please type a name for the composite grammar.", uri.trimFileExtension().segment(uri.segmentCount()-1) + "_composite.bnf", null); di.open(); String fname = di.getValue(); String loc = uri.trimFileExtension().trimSegments(1).toPlatformString(true); String floc = loc.concat("/" + fname); IPath filePath = new Path(floc); 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(); } String coreName = null; // get the core grammar EList imports = ((EtsiBnfImpl) xtextResource.getParseResult().getRootNode().getElement()).getImportSection().getImports(); for(int j=0; j< imports.size(); j++) { if(imports.get(j).getGrammarType().equals("core")) coreName=imports.get(j).getImportURI(); } IPath corePath = new Path(loc.concat("/" + coreName)); IFile core = ResourcesPlugin.getWorkspace().getRoot().getFile(corePath); createNewLine("grammar "+ "remame;" + '\n'); String fp2 = core.getFullPath().toString(); URI coreUri = URI.createPlatformResourceURI(fp2,true); Resource coreResource = set.getResource(coreUri, true); if(coreResource instanceof XtextResource ) coreGrammar = (XtextResource) coreResource; //get the package grammars packageGrammars = new LinkedList(); deltas = new LinkedList(); EList packages = ((EtsiBnfImpl) xtextResource.getParseResult().getRootNode().getElement()).getImportSection().getImports(); for(int j=0; j extensions = new LinkedList(); String ruleC = null; for(AbstractNode extension: NodeUtil.getAllContents( xtextResource.getParseResult().getRootNode())) { if(extension.getElement() instanceof GlobalCombinator) global=((GlobalCombinator) extension.getElement()).getLogic(); if(extension.getElement() instanceof RuleCombinator) if(((Rule) node.getElement()).getName() .equals(((RuleCombinator) extension.getElement()).getName())) ruleC=((RuleCombinator) extension.getElement()).getLogic(); if(extension.getElement() instanceof HookCombinator){ if(((Rule) node.getElement()).getName() .equals(((HookCombinator) extension.getElement()).getName())) extensions.add(extension); } } if(extensions.size()==0) createNewLine(removeNewLines(node) + '\n'); else { createNewLine(handleExtensions(node, extensions, ruleC).trim() + '\n'); } } private String handleExtensions(AbstractNode node, LinkedList extensions, String ruleC) { int oldOffset=0; int newOffset=0; String fullRule = ((Rule) node.getElement()).getName().trim() + " ::= "; while(extensions.size()>0) { AbstractNode current = selectFirstExtension(extensions); newOffset=((HookCombinator) current.getElement()).getRuleext(); fullRule=fullRule.concat(splitRule(node, oldOffset, newOffset)); fullRule=fullRule.concat(resolveReferences(((HookCombinator) current.getElement()), ruleC)); oldOffset=newOffset; } fullRule=fullRule.concat(splitRule(node, newOffset, Integer.MAX_VALUE)); return fullRule; } //returns the portion of the rule between startOffset and endOffset private String splitRule(AbstractNode node, int startOffset, int endOffset) { EList leaves = node.getLeafNodes(); boolean rightSide=true; String temp = ""; int waiting=0; for(int i=0; iwaiting) { waiting++; continue; } waiting = Integer.MAX_VALUE; temp=temp.concat(leaves.get(i).serialize().trim() + " "); startOffset++; } return temp; } /* * given a hook combinator, return the string of the full concatenated extensions at the point */ private String resolveReferences(HookCombinator hookCombinator, String ruleC) { EList labels = hookCombinator.getLABEL(); if(labels.size()==1) { /* * take the only label and find the corresponding delta grammar * in that delta grammar, take the rule with the same name and the same extension point * and return its left side */ return resolveSingleReference(labels.get(0), hookCombinator); } String combinator=null; if(hookCombinator.getLogic()!=null) combinator=hookCombinator.getLogic(); else if(ruleC!=null) combinator=ruleC; else if(global!=null) combinator=global; else combinator="/and"; if(combinator.equals("/and")) { String temp = ""; for(int i=0; i-1; i--) { temp=temp.concat(resolveSingleReference(labels.get(i),hookCombinator)); } return temp; } if(combinator.equals("/or")) { String temp = "( "; String temp2 = null; boolean illegal=false; for(int i=0; i0; i--) { // temp=temp.concat(resolveSingleReference(labels.get(i), hookCombinator) + " | "); // } // // temp=temp.concat(resolveSingleReference(labels.get(0), hookCombinator) + ") "); // return temp; // // } if(combinator.equals("/any")) { String temp2 = null; boolean illegal=false; String temp = "( "; for(int i=0; i-1; i--) { temp=temp.concat(resolveSingleReference(labels.get(i),hookCombinator)); } temp=temp.concat(")) "); return temp; } if(combinator.equals("/together")) { String temp = "(( "; for(int i=0; i-1; i--) { temp=temp.concat(resolveSingleReference(labels.get(i),hookCombinator)); } temp=temp.concat(")) "); return temp; } return " \" operator other than and, andr, or, or interleave \" "; } private String resolveSingleReference(String label, HookCombinator hookCombinator) { URI grammarURI = deltas.get(Character.getNumericValue(label.charAt(label.length()-1))-1); XtextResourceSet set = new XtextResourceSet(); Resource resource = set.getResource(grammarURI, true); if (resource instanceof XtextResource) { XtextResource deltaG = (XtextResource) resource; AbstractNode rule = selectRule( hookCombinator.getName(), hookCombinator.getRuleext(), deltaG.getParseResult().getRootNode()); return splitRule(rule, 0, Integer.MAX_VALUE); } return "error - file isn't a Xtext Resource"; } private AbstractNode selectRule(String ruleName, int extension, CompositeNode grammar) { AbstractNode rule = null; for(AbstractNode currentRule: NodeUtil.getAllContents(grammar)) { if( (currentRule.getElement() instanceof ExtRule) && (((ExtRule) currentRule.getElement()).getName().equals(ruleName)) && (((ExtRule) currentRule.getElement()).getRuleext()==extension)) return currentRule; } return rule; } private AbstractNode selectFirstExtension(LinkedList rules) { AbstractNode first = rules.get(0); int index = 0; for(int i=0; i ((HookCombinator) rules.get(i).getElement()).getRuleext()) { first=rules.get(i); index=i; } } rules.remove(index); return first; } private String removeNewLines(AbstractNode node) { EList leaves = node.getLeafNodes(); String temp = ""; for(int i=0; i