/* Parser.java * * Copyright (c) 2000, Benjamin Fallenstein * * You may use and distribute under the terms of either the GNU Lesser * General Public License, either version 2 of the license or, * at your choice, any later version. Alternatively, you may use and * distribute under the terms of the XPL. * * See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of * the licenses. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README * file for more details. * */ /* * Written by Benjamin Fallenstein */ package org.zaubertrank; import org.gzigzag.*; import java.util.*; /** A parser for zaubertrank programs. * Currently micro-level: the biggest structure recognized is one statement. */ public class Parser { public static final String rcsid = "$Id: Parser.java,v 1.1 2002/10/07 12:37:35 tuukkah Exp $"; public static boolean dbg = false; static final void p(String s) { if(dbg) System.out.println(s); } static final void pa(String s) { System.out.println(s); } static Object NULL = new Object(); static public final String paramdim = "d.2"; // parameter list dim static public final String valuedim = "d.1"; static public final String recorddim = "d.1"; static public final String sequencedim = "d.zaubertrank-list"; static public final String textdim = "d.zaubertrank-txt-alt"; static public final String textrankdim = "d.2"; static public final String textgrammardim = "d.1"; static public final String grammardim = "d.zaubertrank-grammar-list"; static public final String decdim = "d.zaubertrank-declarations"; /** A reference to an ExpNode param in a certain grammatical form. */ static public final class DecRef { int i; GrammarNode g; public DecRef(int i, GrammarNode g) { this.i = i; this.g = g; } } /** A reference to a certain ExpNode in a certain grammatical form. * The difference to DecRef is that DecRef contains only a param number * and a GrammarNode; additionally, an ExpNode is needed to read the * actual text. */ static public final class ExpRef { ExpNode e; GrammarNode g; public ExpRef(ExpNode e, GrammarNode g) { this.e = e; this.g = g; } public Object[] getText() { return e.getText(g); } } static public final class TypeRef { TypeNode t; GrammarNode g; public TypeRef(TypeNode t, GrammarNode g) { this.t = t; this.g = g; } public ZZCell[] getText() { return t.getText(g); } } static public class Node { public ZZCell c; public boolean equals(Node other) { return c.equals(other.c); } } /** A node declaring a grammatical way to utter a type. * Example: English noun ("the person" // "which person?") * Example: English statement ("the ball is red" // "what is true?") * Example: English genitive ("the person's" // "whose?") * etc. */ static public class GrammarNode extends Node { public GrammarNode(ZZCell c) { this.c = c.getRootclone(); if(!this.c.h(grammardim).equals(this.c.getSpace().getHomeCell())) throw new ZZError("Attempt to create GrammarNode from " + "non-grammar cell "+this.c); } public GrammarNode(ZZSpace sp) { this.c = sp.getHomeCell().N(grammardim, 1); } } static ZZCell[] readText(ZZCell c, GrammarNode g) { ZZCell root = c.intersect(textdim, 1, g.c, "d.clone", 1); p("Parse intersect "+c+" and "+g.c+" gives "+root); if(root == null) return null; return root.readRank(textrankdim, 1, false); } static void writeText(ZZCell c, GrammarNode g, ZZCell[] tc) { ZZCell here = g.c.zzclone(); c.insert(textdim, 1, here); for(int i=0; i= params.length || params[i] == null) continue; if(params[i].c.s(valuedim, -1) != null) params[i].c.disconnect(valuedim, -1); here.connect(valuedim, 1, params[i].c); } } /** Change a param in the structure. */ public void setParam(int nr, ExpNode val) { ZZCell var = c.getOrNewCell(paramdim, nr+1); if(var.s(valuedim) != null) var.disconnect(valuedim, 1); if(val.c.s(valuedim, -1) != null) val.c.disconnect(valuedim, -1); var.connect(valuedim, 1, val.c); } /** Read the text for a given GrammarNode. * Returns an Object[] array where the Objects are ZZCells * (which contain a piece of the text) ExpRef objects, or TypeRef * objects. *
* NOTE: there is no corresponding setText function because the * text is deducted from params[] and dec.getText(). */ public Object[] getText(GrammarNode g) { Object[] res = dec.getText(g); if(res == null) return null; for(int i=0; i