@Override public Void visit(TermCons c, Void _) { Production prod = c.getProduction(); builder.append("`"); if (prod.isListDecl() && c.getContents().size() == 2) { UserList list = prod.getListDecl(); builder.append('_'+list.getSeparator()+prod.getSort()+'_'); } else { builder.append(prod.getKLabel()); } builder.append("`"); builder.append('('); boolean listOp = false; for (ProductionItem i : c.getProduction().getItems()) { if (i instanceof NonTerminal && ((NonTerminal)i).getName().equals("KList")) { listOp = true; break; } } boolean first = true; for (Term t : c.getContents()) { if (!first) { builder.append(", "); } first = false; if (listOp) { visitNodeOrKList(t); } else { this.visitNode(t); } } builder.append(')'); return null; }
/** * This methos takes a list of productions with the same kLabel, and finds the maximum arity. This * is needed to avoid situations where there might be more productions with different arities * belonging to same label, for example: * * <p>syntax Foo ::= Bar "*" Bar [klabel(Foo)] syntax Foo ::= Bar "*" [klabel(Foo)] * * @param productions * @return */ private int getMaxArityForProductions(List<Production> productions) { int max = productions.get(0).getArity(); if (productions.size() > 1) { for (Production production : productions.subList(1, productions.size())) { if (production.getArity() > max) { max = production.getArity(); } } } return max; }
@Override public boolean equals(Object obj) { if (obj == null) return false; if (obj == this) return true; if (!(obj instanceof Production)) return false; Production prd = (Production) obj; if (this.sort != null && prd.getSort() != null) if (!this.sort.equals(prd.getSort())) return false; if (this.sort == null && prd.getSort() != null) return false; if (prd.getItems().size() != this.items.size()) return false; for (int i = 0; i < this.items.size(); i++) { if (!prd.getItems().get(i).equals(items.get(i))) return false; } String klabel1 = prd.getAttributes().get("klabel"); String klabel2 = getAttributes().get("klabel"); if ((klabel1 == null && klabel2 != null) || (klabel1 != null && klabel2 == null)) { return false; } if (klabel1 != null && klabel2 != null && klabel1.equals(klabel2)) { return false; } return true; }
public static Production makeFunction( String funSort, String funName, String argSort, org.kframework.kil.loader.Context context) { List<ProductionItem> prodItems = new ArrayList<ProductionItem>(); prodItems.add(new Terminal(funName)); prodItems.add(new Terminal("(")); prodItems.add(new Sort(argSort)); prodItems.add(new Terminal(")")); Production funProd = new Production(new Sort(funSort), prodItems); funProd.addAttribute(new Attribute("prefixlabel", funName)); if (MetaK.isComputationSort(funSort)) { funProd.addAttribute(new Attribute("klabel", funName)); String consAttr = funSort + "1" + funName + "Syn"; funProd.addAttribute(new Attribute("cons", consAttr)); context.conses.put(consAttr, funProd); context.putLabel(funProd, consAttr); } return funProd; }
private static String getSortAndFunctionDeclarations( Definition definition, Set<Variable> variables) { Set<Sort> sorts = new HashSet<>(); List<Production> functions = new ArrayList<>(); for (Production production : definition.context().productions) { String smtlib = production.getAttribute(Attribute.SMTLIB_KEY); if (smtlib != null && !SMTLIB_BUILTIN_FUNCTIONS.contains(smtlib) && !smtlib.startsWith("(")) { functions.add(production); sorts.add(Sort.of(production.getSort())); for (int i = 0; i < production.getArity(); ++i) { sorts.add(Sort.of(production.getChildSort(i))); } } } for (Variable variable : variables) { sorts.add(variable.sort()); } if (!Sets.intersection(sorts, RESERVED_Z3_SORTS).isEmpty()) { throw new UnsupportedOperationException("do not use sorts " + RESERVED_Z3_SORTS); } StringBuilder sb = new StringBuilder(); for (Sort sort : Sets.difference(sorts, SMTLIB_BUILTIN_SORTS)) { sb.append("(declare-sort "); sb.append(sort); sb.append(")\n"); } for (Production production : functions) { sb.append("(declare-fun "); sb.append(production.getAttribute(Attribute.SMTLIB_KEY)); sb.append(" ("); List<String> childrenSorts = new ArrayList<>(); for (int i = 0; i < production.getArity(); ++i) { childrenSorts.add(getSortName(production.getChildNode(i))); } Joiner.on(" ").appendTo(sb, childrenSorts); sb.append(") "); sb.append(getSortName(production)); sb.append(")\n"); } return sb.toString(); }
@Override public ASTNode transform(org.kframework.kil.Definition node) { Definition definition = new Definition(context); this.definition = definition; Module singletonModule = node.getSingletonModule(); for (org.kframework.kil.Rule rule : singletonModule.getRules()) { if (!rule.containsAttribute(SymbolicBackend.SYMBOLIC) || rule.containsAttribute(Attribute.PREDICATE.getKey()) || rule.containsAttribute(Attribute.ANYWHERE.getKey())) { continue; } try { definition.addRule((Rule) rule.accept(this)); } catch (TransformerException e) { System.err.println(rule); System.err.flush(); e.printStackTrace(); } } for (String kLabelName : singletonModule.getModuleKLabels()) { definition.addKLabel(KLabelConstant.of(kLabelName, context)); } /* collect the productions which have the attributes strict and seqstrict */ Set<Production> productions = singletonModule.getSyntaxByTag("strict", context); productions.addAll(singletonModule.getSyntaxByTag("seqstrict", context)); for (Production production : productions) { definition.addFrozenKLabel(KLabelConstant.of(production.getKLabel(), context)); } this.definition = null; return definition; }
public final Production getSymbolicProduction(String sort) { assert allowSymbolic(sort); return Production.makeFunction(sort, symbolicConstructor(sort), "K", context); }
public static Term getTerm(Production prod, org.kframework.kil.loader.Context context) { if (prod.isSubsort()) { final Variable freshVar = Variable.getFreshVar(prod.getItems().get(0).toString()); if (prod.containsAttribute("klabel")) { return KApp.of(KLabelConstant.of(prod.getKLabel(), context), freshVar); } return freshVar; } if (prod.isConstant()) { String terminal = ((Terminal) prod.getItems().get(0)).getTerminal(); if (prod.getSort().equals(KSorts.KLABEL)) { return KLabelConstant.of(terminal, context); } else if (prod.getSort().equals(BoolBuiltin.SORT_NAME)) { return BoolBuiltin.kAppOf(terminal); } else if (prod.getSort().equals(IntBuiltin.SORT_NAME)) { return IntBuiltin.kAppOf(terminal); } else if (prod.getSort().equals(StringBuiltin.SORT_NAME)) { return StringBuiltin.kAppOf(terminal); } else { return GenericToken.kAppOf(prod.getSort(), terminal); } } if (prod.isLexical()) { return KApp.of( KLabelConstant.of("#token", context), StringBuiltin.kAppOf(prod.getSort()), Variable.getFreshVar("String")); } TermCons t = new TermCons(prod.getSort(), prod.getCons(), context); if (prod.isListDecl()) { t.getContents().add(Variable.getFreshVar(((UserList) prod.getItems().get(0)).getSort())); t.getContents().add(Variable.getFreshVar(prod.getSort())); return t; } for (ProductionItem item : prod.getItems()) { if (item instanceof Sort) { t.getContents().add(Variable.getFreshVar(((Sort) item).getName())); } } return t; }
public static StringBuilder getSdfForDefinition(Definition def, Context context) { StringBuilder sdf = new StringBuilder("module Integration\n\n"); sdf.append("imports Common\n"); sdf.append("imports KTechnique\n"); sdf.append("imports KBuiltinsBasic\n\n"); sdf.append("exports\n\n"); sdf.append("context-free syntax\n"); DefinitionSDFVisitor psdfv = new DefinitionSDFVisitor(true, context); CollectTerminalsVisitor terminals = new CollectTerminalsVisitor(); psdfv.visitNode(def); terminals.visitNode(def); for (Production p1 : psdfv.listProds) for (Production p2 : psdfv.listProds) if (p1 != p2) { Sort srt1 = ((UserList) p1.getItems().get(0)).getSort(); Sort srt2 = ((UserList) p2.getItems().get(0)).getSort(); if (psdfv.subsorts.contains(new Subsort(srt1, srt2))) psdfv.subsorts.add(new Subsort(p1.getSort(), p2.getSort())); } sdf.append(psdfv.sdf); sdf.append("%% subsorts 1\n"); sdf.append("context-free priorities\n{\n"); // 1 // print Sort -> K > A -> B > K -> Sort for (NonTerminal s : psdfv.userSorts) { if (!s.getSort().isBaseSort()) { sdf.append(" " + StringUtil.escapeSort(s) + " -> K"); // sdf.append(" {cons(\"K12" + StringUtil.escapeSort(s) + "\")}"); sdf.append("\n"); } } sdf.append("} .> {\n"); for (Subsort subs : psdfv.subsorts) { Sort s1 = subs.getSmallSort(); Sort s2 = subs.getBigSort(); if (!s1.isBaseSort() && !s2.isBaseSort()) { sdf.append(" " + StringUtil.escapeSort(s1) + " -> " + StringUtil.escapeSort(s2)); // sdf.append(" {cons(\"" + StringUtil.escapeSort(s2) + "12" + StringUtil.escapeSort(s1) + // "\")}"); sdf.append("\n"); } } sdf.append("} .> {\n"); for (NonTerminal s : psdfv.userSorts) { if (!s.getSort().isBaseSort()) { sdf.append(" K -> " + StringUtil.escapeSort(s)); // sdf.append(" {cons(\"" + StringUtil.escapeSort(s) + "12K\")}"); sdf.append("\n"); } } sdf.append("}\n\n"); sdf.append("%% subsorts 1a\n"); sdf.append("context-free priorities\n{\n"); // 1 // print Sort -> K > A -> B > K -> Sort for (NonTerminal s : psdfv.userSorts) { if (!s.getSort().isBaseSort()) { sdf.append(" " + StringUtil.escapeSort(s) + " -> K"); // sdf.append(" {cons(\"K12" + StringUtil.escapeSort(s) + "\")}"); sdf.append("\n"); } } sdf.append("} .> {\n"); for (NonTerminal s : psdfv.userSorts) { if (!s.getSort().isBaseSort()) { sdf.append(" K -> " + StringUtil.escapeSort(s)); // sdf.append(" {cons(\"" + StringUtil.escapeSort(s) + "12K\")}"); sdf.append("\n"); } } sdf.append("}\n\n"); sdf.append("%% subsorts 2\n"); // print K -> Sort > Sort -> K sdf.append("context-free priorities\n{\n"); for (NonTerminal s : psdfv.userSorts) { if (!s.getSort().isBaseSort()) { sdf.append(" K -> " + StringUtil.escapeSort(s)); // sdf.append(" {cons(\"" + StringUtil.escapeSort(s) + "12K\")}"); sdf.append("\n"); } } sdf.append("} .> {\n"); for (NonTerminal s : psdfv.userSorts) { if (!s.getSort().isBaseSort()) { sdf.append(" " + StringUtil.escapeSort(s) + " -> K"); // sdf.append(" {cons(\"K12" + StringUtil.escapeSort(s) + "\")}"); sdf.append("\n"); } } sdf.append("}\n"); sdf.append("context-free syntax\n"); for (Production p : psdfv.outsides) { if (p.isListDecl()) { UserList si = (UserList) p.getItems().get(0); sdf.append( " " + StringUtil.escapeSort(si.getSort()) + " " + StringUtil.enquoteCString(si.getSeparator()) + " " + StringUtil.escapeSort(p.getSort()) + " -> " + StringUtil.escapeSort(p.getSort())); sdf.append(" {cons(\"" + context.getConses().inverse().get(p) + "\")}\n"); sdf.append(" \"." + p.getSort() + "\" -> " + StringUtil.escapeSort(p.getSort())); sdf.append(" {cons(\"" + StringUtil.escapeSort(p.getSort()) + "1Empty\")}\n"); } else if (p.containsAttribute("bracket")) { // don't add bracket attributes added by the user } else { sdf.append(" "); List<ProductionItem> items = p.getItems(); for (int i = 0; i < items.size(); i++) { ProductionItem itm = items.get(i); if (itm instanceof Terminal) { Terminal t = (Terminal) itm; sdf.append(t.toString() + " "); } else if (itm instanceof NonTerminal) { NonTerminal srt = (NonTerminal) itm; // if we are on the first or last place and this sort is not a list, just print the sort if (i == 0 || i == items.size() - 1) { sdf.append(StringUtil.escapeSort(srt) + " "); } else { // if this sort should be inserted to avoid the priority filter, then add it to the // list psdfv.insertSorts.add(srt); String tempstr = srt.toString(); if (tempstr.endsWith("CellSort") || tempstr.endsWith("CellFragment")) tempstr = "Bag"; sdf.append("InsertDz" + StringUtil.escapeSort(tempstr) + " "); } } } sdf.append("-> " + StringUtil.escapeSort(p.getSort())); sdf.append(SDFHelper.getSDFAttributes(p, context.getConses()) + "\n"); } } for (NonTerminal ss : psdfv.insertSorts) sdf.append( " " + StringUtil.escapeSort(ss) + " -> InsertDz" + StringUtil.escapeSort(ss) + "\n"); sdf.append("\n"); for (NonTerminal s : psdfv.userSorts) { if (!s.getSort().isBaseSort()) { sdf.append( " K CastTypeDz \"" + s.toString() + "\" -> VariableDz {cons(\"" + StringUtil.escapeSort(s) + "1Cast\")}\n"); sdf.append( " K CastTypeDz \"" + s.toString() + "{\" TagListDz \"}\" -> VariableDz {cons(\"" + StringUtil.escapeSort(s) + "1CastAttr\")}\n"); } } sdf.append(" K CastTypeDz \"K\" -> VariableDz {cons(\"K1Cast\")}\n"); sdf.append(" K CastTypeDz \"KItem\" -> VariableDz {cons(\"KItem1Cast\")}\n"); sdf.append( " K CastTypeDz \"K{\" TagListDz \"}\" -> VariableDz {cons(\"K1CastAttr\")}\n"); sdf.append( " K CastTypeDz \"KItem{\" TagListDz \"}\" -> VariableDz {cons(\"KItem1CastAttr\")}\n"); for (NonTerminal s : psdfv.userSorts) { if (!s.getSort().isBaseSort()) { sdf.append( " " + StringUtil.escapeSort(s) + "DzVar -> " + StringUtil.escapeSort(s) + "\n"); } } sdf.append("\n"); sdf.append(" VariableDz -> K\n"); sdf.append("\n\n"); for (Sort sort : psdfv.constantSorts) { String s = StringUtil.escapeSort(sort); sdf.append(" Dz" + s + " -> " + s + " {cons(\"" + s + "1Const\")}\n"); } sdf.append("\n"); // sdf.append(" DzDzINT -> DzDzInt\n"); // sdf.append(" DzDzID -> DzDzId\n"); // sdf.append(" DzDzSTRING -> DzDzString\n"); // sdf.append(" DzDzFLOAT -> DzDzFloat\n"); sdf.append("\n"); sdf.append("lexical syntax\n"); for (Production p : psdfv.constants) { sdf.append( " " + p.getItems().get(0) + " -> Dz" + StringUtil.escapeSort(p.getSort()) + "\n"); } sdf.append("\n\n%% sort predicates\n"); // print is<Sort> predicates (actually KLabel) for (NonTerminal sort : psdfv.userSorts) { if (!sort.getSort().isKSort()) { sdf.append( " \"" + AddPredicates.syntaxPredicate(sort.getSort()) + "\" -> DzKLabel\n"); } if (AddSymbolicK.allowKSymbolic(sort.getSort())) { sdf.append( " \"" + AddPredicates.symbolicPredicate(sort.getSort()) + "\" -> DzKLabel\n"); sdf.append( " \"" + AddSymbolicK.symbolicConstructor(sort.getSort()) + "\" -> DzKLabel\n"); } } sdf.append("\n\n"); sdf.append("\n%% terminals reject\n"); sdf.append(SDFHelper.getFollowRestrictionsForTerminals(terminals.terminals)); sdf.append("context-free restrictions\n"); for (NonTerminal s : psdfv.userSorts) { if (!s.getSort().isBaseSort()) { sdf.append(" " + StringUtil.escapeSort(s) + "DzVar -/- [a-zA-Z0-9\\{]\n"); } } sdf.append(" VariableDz -/- [a-zA-Z0-9\\{]\n"); sdf.append("lexical restrictions\n"); sdf.append("%% some restrictions to ensure greedy matching for user defined constants\n"); // sdf.append(" DzDzInt -/- [0-9]\n"); sdf.append(" \"is\" -/- [\\#A-Z]\n"); sdf.append("\n"); // lexical rules sdf.append("lexical syntax\n"); java.util.Set<Sort> lexerSorts = new HashSet<>(); for (Production p : psdfv.lexical) { Lexical l = (Lexical) p.getItems().get(0); lexerSorts.add(p.getSort()); sdf.append( " " + l.getLexicalRule() + " -> " + StringUtil.escapeSort(p.getSort()) + "Dz\n"); if (l.getFollow() != null && !l.getFollow().equals("")) { psdfv.restrictions.add(new Restrictions(new NonTerminal(p.getSort()), null, l.getFollow())); } if (!p.containsAttribute("noAutoReject")) { // reject all terminals that match the regular expression of the lexical production if (p.containsAttribute("regex")) { Pattern pat = Pattern.compile(p.getAttribute("regex")); for (Terminal t : terminals.terminals) { Matcher m = pat.matcher(t.getTerminal()); if (m.matches()) sdf.append( " " + t.toString() + " -> " + StringUtil.escapeSort(p.getSort()) + "Dz {reject}\n"); } } else { // if there is no regex attribute, then do it the old fashioned way, but way more // inefficient // add rejects for all possible combinations for (Terminal t : terminals.terminals) { sdf.append( " " + t.toString() + " -> " + StringUtil.escapeSort(p.getSort()) + "Dz {reject}\n"); } } } } // adding cons over lexical rules sdf.append("context-free syntax\n"); for (Sort s : lexerSorts) { sdf.append( " " + StringUtil.escapeSort(s) + "Dz -> " + StringUtil.escapeSort(s) + " {cons(\"" + StringUtil.escapeSort(s) + "1Const\")}\n"); } sdf.append("\n\n"); // follow restrictions sdf.append("context-free restrictions\n"); for (Restrictions r : psdfv.restrictions) { if (r.getTerminal() != null && !r.getTerminal().getTerminal().equals("")) sdf.append( " " + StringUtil.enquoteCString(r.getTerminal().getTerminal()) + " -/- " + r.getPattern() + "\n"); else sdf.append( " " + StringUtil.escapeSort(r.getNonTerminal()) + " -/- " + r.getPattern() + "\n"); } return sdf; }
public int arity() { return production.getArity(); }