private static void DCGGoal(Term t, ref TermNode body, ref Term remainder, ref bool embedded) { Term temp; if (t.IsString || t is Cut) body.Append(t); else if (t.Functor == Parser.CURL) { while (t.Arity == 2) { body.Append(t.Arg(0)); t = t.Arg(1); embedded = true; } } else if (t.IsList) { temp = new Term(); if (t == NULLLIST) t = temp; else t.SetRightmostArg(temp); if (embedded) { body.Append(new Term(Parser.EQ, remainder, t, FType.comp, OType.xfx, 700)); embedded = false; } else remainder.Bind(t); // in this case, nothing is appended to body, which may be left empty (e.g. t-->[x]) remainder = temp; } else if (t.IsAtom || t.IsCompound) { t = new DCGTerm(t, ref remainder); body.Append(t); } else if (t.IsVar) PrologIO.Error("Variable not allowed in DCG-clause: {0}", t.VarName()); else PrologIO.Error("Illegal term in DCG-clause: {0}", t); }
private void DCGBracketList(TerminalSet _TS, out Term term) { Term head; ArrayList elements = null; GetSymbol(new TerminalSet(LCuBracket), true, true); GetSymbol(new TerminalSet(LeftParen, Identifier, IntLiteral, RealLiteral, StringLiteral, Operator, Atom, Anonymous, CutSym, LSqBracket, LCuBracket, RCuBracket, PrologString), false, true); if (symbol.IsMemberOf(LeftParen, Identifier, IntLiteral, RealLiteral, StringLiteral, Operator, Atom, Anonymous, CutSym, LSqBracket, LCuBracket, PrologString)) { PrologTerm(new TerminalSet(RCuBracket), out head); elements = head.ArgumentsToArrayList(true); } GetSymbol(new TerminalSet(RCuBracket), true, true); term = new DCGTerm(); if (elements != null) for (int i = elements.Count - 1; i >= 0; i--) term = new DCGTerm((Term)elements[i], term); }
// DCG stuff public TermNode ToDCG(ref Term lhs) // cf. Side Notes SN3 { TermNode body = new TermNode(); Term result = null; Term inVar = new Term(); Term inVarSave = inVar; Term outVar = inVar; lhs = new DCGTerm(lhs, ref outVar); // outVar becomes new term Term remainder; try { readingDCGClause = true; ArrayList alternatives = AlternativesToArrayList(); for (int i = 0; i < alternatives.Count; i++) { Term alt = (Term)alternatives[i]; bool embedded = (alternatives.Count > 1); ArrayList terms = alt.ArgumentsToArrayList(true); // flatten clause such as X --> (A, B), C. body.Clear(); remainder = inVarSave; for (int ii = 0; ii < terms.Count; ii++) DCGGoal((Term)terms[ii], ref body, ref remainder, ref embedded); // create a term-tree from the array if (i == 0) result = TermSeq(body); else result = new Term(Parser.SEMI, result, TermSeq(body), FType.comp, OType.xfy, 1100); remainder.Bind(outVar); } } finally { readingDCGClause = false; } return (result == null) ? null : result.ToGoalList(); // empty body treated similar to null }