private void addNonTerminal(String EBNF) { String p = "<([\\w-]+)>[\\s]*::=(" + "([\\s]*(<[\\w-]+>|(\"[^\"]*\")|[|\\[\\]{}])" + ")+)"; Matcher m = Pattern.compile(p).matcher(EBNF); m.find(); NonTerminal nt = new NonTerminal(m.group(1)); List<? extends EBNFBranch> branches = EBNFBranch.getBranches(m.group(2)); assert (branches.size() > 0); if (nonTerminals.size() == 0) { startSymbol = nt; } nonTerminals.put(nt, branches); }
/** * SIGH... * * @return */ public BNF toBNF() { // first thing first, make a deep copy of current EBNF // then play / return with the copy EBNF ebnf = clone(); // auto generate new non terminal names StringIterator quanNames = new StringIterator("quan_{000}"); int oldHash = ebnf.hashCode(); int newHash = ebnf.hashCode(); boolean exceptionTriggered; do { oldHash = newHash; exceptionTriggered = false; Iterator<NonTerminal> i = ebnf.nonTerminals.keySet().iterator(); try { // travel through all non terminals while (i.hasNext()) { NonTerminal iii = i.next(); Iterator<? extends EBNFBranch> j = ebnf.nonTerminals.get(iii).iterator(); // travel through all branches for each non terminal while (j.hasNext()) { EBNFBranch jjj = j.next(); List l = jjj.getElementList(); // travel through all elements for each branch for (int n = 0; n < l.size(); n++) { if (l.get(n) instanceof Quantification) { // found a quantification Quantification q = ((Quantification) l.get(n)); // substitude it with a new non terminal NonTerminal newnt = new NonTerminal(quanNames.next()); l.set(n, newnt); // modify the element list for the new nt a little bit List<EBNFBranch> li = (List<EBNFBranch>) q.getBranchList(); if ((q.getMaxOccurrance() == 1) && (q.getMinOccurrance() == 0)) { // [..] boolean containsEpsilon = false; for (int k = 0; k < li.size(); k++) { if (Terminal.epsilon.equals(li.get(k).getElementList().get(0))) { // this branch contains epsilon // (branches that contain epsilon contains only 1 element) containsEpsilon = true; } } // add new epsilon branch if currently don't have one if (!containsEpsilon) { li.add(new EBNFBranch()); } } else if ((q.getMaxOccurrance() == -1) && (q.getMinOccurrance() == 0)) { boolean containsEpsilon = false; // {...} for (int k = 0; k < li.size(); k++) { if (Terminal.epsilon.equals(li.get(k).getElementList().get(0))) { containsEpsilon = true; // keep the only one epsilon branch untouched } else { // add the new non terminal to the end of // each non epsilon branch li.get(k).getElementList().add(newnt); } } if (!containsEpsilon) { li.add(new EBNFBranch()); } } // add the new non terminal to new EBNF ebnf.nonTerminals.put(newnt, li); } } } } } catch (ConcurrentModificationException e) { exceptionTriggered = true; } newHash = ebnf.hashCode(); } while ((newHash != oldHash) || exceptionTriggered); return new BNF(ebnf.startSymbol, ebnf.nonTerminals); }