|
Server : Apache/2.4.62 System : FreeBSD fbsdweb2.web.rcn.net 14.1-RELEASE FreeBSD 14.1-RELEASE releng/14.1-n267679-10e31f0946d8 GENERIC amd64 User : www ( 80) PHP Version : 8.3.8 Disable Function : NONE Directory : /domains/markrose/ |
Upload File : |
<HTML>
<HEAD>
<meta http-equiv="content-type" content="text-html; charset=utf-8">
<TITLE>gtg - Generative Tree Gadget</TITLE>
<style>
h2
{color:#A60000;}
h3
{color:#C08700;}
h4
{color:#C08700;}
h5
{color:#C08700;}
h6
{color:#C08700;}
tt
{color:#A60000;
font-weight:bold;
font-family:"Gentium";}
</style>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<form action="" name="theform">
<script language="javascript" type="text/javascript">
// Script (C) 2018 by Mark Rosenfelder.
// Use Lexicon to build argument structure
// Morphology should be done in some easy way
// Build VP struture, use xforms to 'make it real'
var theform;
var lex;
var psr;
var showpsr = false;
var fullform = false;
var embedding = false;
var inf = false;
// Random int from 0 to n
function randomInt(max)
{
return Math.floor(Math.random() * max) ;
}
// Return the word portion of a lexeme (before the :)
function theword(s)
{
if (s == null || s == "") return "";
var i = s.indexOf(':');
if (i == -1) return s;
return s.substr(0,i);
}
// Return the category of a lexeme (just after the :)
function thehead(s)
{
if (s == null || s == "") return "";
var spp = s.split(":")
if (spp.length < 2) return s;
return spp[1];
}
// Return the third parameter of a lexical item
function thearg(s)
{
var spp = s.split(":")
if (spp.length < 2) return "";
return spp[2];
}
// Create a node in the tree
function Node(h, left, mid, right) {
var node = {head:"X", left:"", mid:"", right:""};
node.head = h;
node.left = left;
node.mid = mid;
node.right = right;
}
// Is this a left bracket?
function Bra(t) {
return t.charAt(0) == '[';
}
// Is this a right bracket?
function Ket(t) {
return t == "]";
}
// General function: replace the word in a w[] entry.
// That is, replace just the part up to the first :
function ReplaceWord(wd, tgt) {
var colon = wd.indexOf(':');
return tgt + wd.substr(colon);
}
// Similar, but replaces parameter n
// If n is 0, use ReplaceWord, it's faster
function ReplaceParm(wd, n, tgt) {
var partz = wd.split(":");
var s = "";
for (var i = 0; i < partz.length; i++) {
if (s != "") s += ":";
if (i == n)
s += tgt;
else
s += partz[i];
}
return s;
}
// Given a verb and the desired form, change the verb to that form.
// Example:
// tgt = Prog
// sit:V:PP:s sits Past sat Prog sitting Perf sat
// change "sit" to "sitting"
function Inflect(wd, tgt)
{
var vpp = wd.split(":");
if (vpp.length < 4) return wd;
// STD this should probly be in xform lg instead
// For N/Pron, insert number as well
if (vpp[1] == "N" || vpp[1] == "Pron")
tgt = theNumber(wd) + tgt;
var forms = vpp[3].split(" ");
for (var i = 0; i < forms.length; i += 2) {
if (forms[i] == tgt)
return ReplaceWord(wd, forms[i+1]);
}
return wd;
}
// Does this space-separated list contain element tgt or tgt2?
function Includes(s, tgt, tgt2) {
var spp = s.split(" ");
for (var i = 0; i < spp.length; i++) {
if (spp[i] == tgt || spp[i] == tgt2) return true;
}
return false;
}
var t;
var o = null;
var oo = null;
var w = null;
// Apply a rule
// If rule doesn't apply, this will do nothing
function Apply(r) {
oo = null;
var partz = r.split("=");
if (partz.length < 2) return false;
var doMe = new Array(o.size);
var doSome = false;
// Mark elements that are selected by this rule
for (var i = 0; i < o.length; i++) {
var word = o[i];
doMe[i] = theword(word) == partz[0];
if (doMe[i])
doSome = true;
}
if (!doSome)
return false;
// Some rules only apply about 1/3 the time
if (partz.length > 2)
if (partz[2] == "?")
if (Math.random() < 0.667)
return false;
// Expand target(s)
oo = new Array();
for (var i = 0; i < o.length;i++) {
if (doMe[i]) {
// This one matches the target; expand it
oo.push("[" + partz[0]);
var expans = partz[1];
var pipe = expans.indexOf('|');
if (pipe != -1) {
// Multiple choice. Bias toward first one
var altz = expans.split("|");
if (Math.random() < 0.33)
expans = altz[0];
else {
expans = altz[randomInt(altz.length)];
// Embed sentences only one level deep
if (embedding && Includes(expans, "S", "Sinf"))
expans = altz[0];
}
}
compz = expans.split(" ");
for (var j = 0; j < compz.length; j++) {
var tgt = compz[j];
if (tgt.charAt(0) == '?') {
// ?X means sometimes insert X
if (Math.random() < 0.33)
oo.push(tgt.substr(1));
} else if (tgt.charAt(0) == '(') {
// (X) means insert 0 to 2 copies of X
tgt = tgt.substr(1, tgt.length - 2);
var r3 = randomInt(3);
for (var k = 0; k < r3; k++)
oo.push(tgt);
} else {
oo.push(tgt);
}
}
oo.push("]");
} else {
oo.push(o[i]);
}
}
return true;
}
// Does element o[i] or w[i] match str?
// Elements syntax: X is a category; :X is a word; X:Y is a word X of category X
// For an XP, write e.g. [NP
function Match(i, str)
{
var cat = str;
var word = "";
var colon = str.indexOf(':');
if (colon != -1) {
cat = str.substr(0,colon);
word = str.substr(colon+1);
}
var catmatch = cat == "" || theword(o[i]) == cat;
var wordsame = word == "" || theword(w[i]) == word;
return catmatch && wordsame;
}
var matches = null;
// Find the sequence str within our sentence (o and w)
// Str can be more than one element
// Return the location within the o array, or -1 if not found
function OFind(o, str)
{
var tgt = str.split(" ");
matches = new Array(tgt.length + 1);
for (var i = 0; i < o.length; i++) {
var ok = false;
var iOrig = i;
for (var j = 0; j < tgt.length && i < o.length; j++) {
ok = Match(i, tgt[j]);
if (!ok) break;
matches[j] = i;
if (Bra(tgt[j])) {
// This is an XP; skip to its end
var level = 0;
for (; i < o.length; i++) {
if (Bra(o[i])) level++;
else if (Ket(o[i])) level--;
if (level == 0) break;
}
}
i++;
}
matches[tgt.length] = i;
i = iOrig;
if (ok) return i;
}
return -1;
}
// Apply a transformation
function Transform(ins, outs)
{
if (OFind(o, ins) == -1) {
t += " - Target not found";
return false;
}
t += " - " + ins + " > " + outs;
oo = new Array();
var ww = new Array();
var remloc = matches[matches.length - 1];
for (var i = 0; i < matches[0]; i++) {
oo.push(o[i]);
ww.push(w[i]);
}
var orig = ins.split(" ");
var repz = outs.split(" ");
for (var i = 0; i < repz.length; i++) {
var el = repz[i];
var el0 = el.charAt(0);
if (el0 == '»') {
// Lexicon lookup
var elz = el.substr(1).split(":");
var wd = Lookup(elz[0]);
if (wd != "") {
if (elz.length == 1)
oo.push(thehead(wd));
else
oo.push(elz[1]);
ww.push(wd);
}
}
else if ('0123456789'.indexOf(el0) == -1) {
// Category
oo.push(el);
ww.push("");
} else {
var r = parseInt(el);
// Element from input string (by number)
if (r >= 0 && r < orig.length) {
for (var j = matches[r]; j < matches[r+1]; j++) {
var wd = w[j];
oo.push(o[j]);
ww.push(wd);
}
}
}
}
for (var i = remloc; i < o.length; i++) {
oo.push(o[i]);
ww.push(w[i]);
}
o = oo;
w = ww;
return true;
}
// Return the clausemates of this V
// STD: decide what direction to go - this could be a checkbox
function VP(o, i) {
var level = 0;
var u = "";
for (var j = i + 1; j < o.length; j++) {
var t = o[j];
if (Bra(t)) {
if (level == 0) u += " " + t.substr(1);
level++;
}
else if (Ket(t)) {
level--;
}
else if (level == 0) u += " " + t;
}
if (u != "") u = u.substr(1);
return u;
}
// Inflect word for plural
function Pluralize(wd)
{
wd = Inflect(wd, "p");
// Add to arg so we know we changed this
wd = ReplaceParm(wd, 2, thearg(wd) + " p");
return wd;
}
// Select lexical items
function Lexicalize(o) {
var w = new Array(o.length);
// For each word in the sentence
for (var i = 0; i < o.length; i++) {
w[i] = "";
// Brackets don't get words
if (Bra(o[i]) || Ket(o[i])) {
continue;
}
// Go through lexicon
var ll = new Array();
for (var j = 0; j < lex.length; j++) {
var wd = lex[j];
if (o[i] == thehead(wd)) {
if (o[i] == "Comp" && inf) {
wd = "inf:Comp";
}
if ((o[i] == "N" || o[i] == "Pron") && Math.random() < 0.33) {
// Select plural for nouns, sometimes
wd = Pluralize(wd);
}
if (o[i] == "V") {
// Verbs must match # of arguments
var vp = VP(o, i);
if (vp != thearg(wd))
continue;
}
ll.push(wd);
}
}
if (ll.length == 0)
continue;
// Select one randomly
var m = randomInt(ll.length);
w[i] = ll[m];
if (w[i] == null) t += "<br/>NULL";
}
return w;
}
// Output tree as unreadable string
// Set fullform to output entire word rather than 1st section
function Stringize(o, w) {
var s = "";
var level = 0;
for (var i = 0; i < o.length; i++) {
var t = o[i];
if (Bra(t)) {
level++;
var c = "Purple";
if (t == "[NP") c = "red";
else if (t == "[PP") c = "orange";
else if (t == "[S") c = "blue";
else if (t == "[TP") c = "green";
s += '<span style="color:' + c + '">';
}
s += t + " ";
if (Ket(t)) {
level--;
s += "</span>";
}
if (w != null && w[i] != null) {
s += '<span style="color:black;font-weight:bold;">';
if (fullform) s += w[i];
else s += theword(w[i]);
s += '</span> ';
}
}
return s;
}
// Output tree as even more unreadable string for phpSyntaxTree
// Should be same as Stringize but: no colors; brackets round words; spaces > %20
function wordbrax(o, w) {
var s = "";
for (var i = 0; i < o.length; i++) {
if (Bra(o[i]) || Ket(o[i]) || w[i] == null)
s += o[i];
else
s += "[" + o[i] + "%20" + w[i] + "]";
}
return s;
}
// Output pronounced words only
function Pronounce(w) {
var s = "";
var punct = ".";
for (var i = 0; i < w.length; i++) {
if (w[i] == null || w[i] == "") continue;
var wd = theword(w[i]);
if (wd == "Q")
punct = "?";
else if (wd != "ø" && wd != "inf" && wd != "past" && wd != "pres") {
if (s != "") s += " ";
s += wd;
}
}
s += punct;
return s.italics();
}
// Find the first element of category cat
function FindFirst(cat) {
var catz = cat.split("|");
for (var i = 0; i < o.length; i++) {
for (var c = 0; c < catz.length; c++)
if (theword(o[i]) == catz[c])
return i;
}
return -1;
}
// Find the first element of word w
function FindFirstWord(tgt) {
for (var i = 0; i < o.length; i++) {
if (w[i] != null && theword(w[i]) == tgt)
return i;
}
return -1;
}
// Insert a word just at a location in both o[] and w[]
function Insert(tgt, wd, cat) {
w.splice( tgt, 0, wd);
o.splice( tgt, 0, cat);
}
// Find first item of class c from position i
// c can list multiple classes separated by |
// special class Aux is in third position
function FindNext(c, i, dir)
{
if (i == -1) i = 0;
var incr = 1;
var iOrig = i;
if (dir == "-") incr = -1;
var cc = c.split("|");
// For each word in the indicated direction
for (i += incr; i >= 0 && i < w.length; i += incr) {
for (var j = 0; j < cc.length; j++) {
if (o[i] == cc[j] || thehead(w[i]) == cc[j])
return i;
}
}
// ±: if + direction failed, try -
if (dir == "±")
return FindNext(c, iOrig, "-");
return -1;
}
// Find the next word
function NextWord(i)
{
for (i++; i < w.length; i++) {
if (w[i] != null && w[i] != "" && theword(w[i]) != "ø")
return i;
}
return -1;
}
// Find the last element of this constituent
function FindEnd(tgt)
{
var level = 0;
for (var i = tgt + 1; i < o.length; i++) {
if (Bra(o[i]))
level++;
else if (Ket(o[i])) {
level--;
if (level < 0)
return i + 1;
}
}
return o.length;
}
// Flip two constituents
function Flip(t1b, t2b)
{
if (t2b < t1b) {
var temp = t2b;
t2b = t1b;
t1b = temp;
}
var t1e = FindEnd(t1b);
var t2e = FindEnd(t2b);
oo = new Array();
ww = new Array();
// Portion before t1 is copied as is
var i = 0;
for (; i < t1b && i < o.length; i++)
{ oo.push(o[i]); ww.push(w[i]); }
// Copy t2 into t1's spot
for (i = t2b; i < t2e && i < o.length; i++)
{ oo.push(o[i]); ww.push(w[i]); }
// Portion in between is copied as is
for (i = t1e; i < t2b && i < o.length; i++)
{ oo.push(o[i]); ww.push(w[i]); }
// Copy t1 into t2's spot
for (i = t1b; i < t1e && i < o.length; i++)
{ oo.push(o[i]); ww.push(w[i]); }
// Portion after t2 is copied as is
for (i = t2e; i < o.length; i++)
{ oo.push(o[i]); ww.push(w[i]); }
o = oo;
w = ww;
}
// Lexicon lookup
function Lookup(item) {
for (var l = 0; l < lex.length; l++) {
if (theword(lex[l]) == item)
return lex[l];
}
return "";
}
// Safe lookahead
function Look(partz, i)
{
if (i + 1 < partz.length)
return partz[i + 1];
else
return "";
}
var rcheck = false;
// Apply a rule, e.g.
// if Prog find V inflect ing
function Xform(x)
{
var partz = x.split(" ");
var tgt = -1;
var clip = "";
var loop = -1;
var nloop = 0;
for (var i = 0; i < partz.length; i++) {
var cmd = partz[i];
if (cmd == "sub") {
if (!embedding)
return false;
}
if (cmd == "main") {
if (embedding)
return false;
}
if (cmd == "maybe") {
// Optional transformations happen at a fixed 1/3 rate
if (Math.random() < 0.667)
return false;
}
if (cmd == "checkif") {
var ins = "";
for (i = i + 1; i < partz.length; i++) {
if (ins != "") ins += " ";
ins += partz[i];
}
rcheck = OFind(o, ins) != -1;
t += " check is " + rcheck;
return;
}
if (cmd == "yes") {
if (!rcheck) return;
}
if (cmd == "no") {
if (rcheck) return;
}
if (cmd == "start") {
// Remember where we are
loop = i;
}
if (cmd == "loop") {
// Loop back to remembered location
nloop++;
if (nloop < 10)
i = loop;
}
if (cmd == "if") {
// Existence check
var want = true;
if (Look(partz, i) == "no") {
want = false;
i++;
}
var item = Look(partz, i); i++;
if (item == "word") {
item = Look(partz,i); i++;
tgt = FindFirstWord(item);
} else
tgt = FindFirst(item);
t += " searching " + item + " " + tgt;
// If that failed, exit
if (want && tgt == -1)
return;
if (!want && tgt != -1)
return;
continue;
}
if (cmd == "find") {
// Find an item; save it as the target
// STD word
var item = Look(partz, i); i++;
var start = 0;
var dir = "+";
if (item == "next") {
start = tgt;
item = Look(partz, i); i++;
} else if (item == "previous") {
start = tgt;
item = Look(partz, i); i++;
dir = "-";
}
tgt = FindNext(item, start, dir);
t += " finding " + tgt;
if (tgt == -1)
return;
continue;
}
if (cmd == "object") {
// Find the sentence's object (its [NP)
tgt = FindNext("[NP", o.length, "-");
if (tgt < FindNext("[VP", o.length, "-"))
tgt = -1; // we found the subject
if (tgt == -1) return;
}
if (cmd == "subject") {
// Find the sentence's subject (its [NP)
tgt = FindNext("[NP", 0, "+");
if (tgt == -1) return;
}
if (cmd == "ifword" && tgt != -1) {
// Is the next actual word equal to the one specified?
while (tgt < o.length && theword(w[tgt]) == "")
tgt++;
var item = Look(partz, i); i++;
t += " ifword " + item + " " + theword(w[tgt]);
if (item != theword(w[tgt]))
return;
}
if (cmd == "inflect" && tgt != -1) {
// Inflect current word with the given inflection
var afx = Look(partz, i); i++;
if (afx == "clip") afx = clip;
t += " inflecting " + theword(w[tgt]) + "+" + afx;
w[tgt] = Inflect(w[tgt], afx);
continue;
}
if (cmd == "transform") {
// Transform one structure into another
var ins = "";
for (i = i + 1; i < partz.length; i++) {
if (partz[i] == "into") break;
if (ins != "") ins += " ";
ins += partz[i];
}
var outs = "";
for (i = i + 1; i < partz.length; i++) {
if (partz[i] == "end") break;
if (outs != "") outs += " ";
outs += partz[i];
}
Transform(ins, outs);
}
if (cmd == "copy" && tgt != -1) {
// Copy word information to clipboard
if (Look(partz, i) == "num") {
i++;
clip = theNumber(w[tgt]);
} else {
clip = w[tgt];
if (clip == "")
clip = "#" + tgt;
}
}
if (cmd == "cut" && tgt != -1) {
// Copy plus zero out old contents
clip = w[tgt];
w[tgt] = "ø";
}
if (cmd == "paste" && tgt != -1 && clip != "") {
// Paste clipboard to target word
t += " paste to " + theword(w[tgt]);
if (w[tgt] == null || w[tgt] == "" || w[tgt] == "ø")
w[tgt] = clip;
else {
if (clip == "s" || clip == "p") {
w[tgt] = Pluralize(w[tgt]);
} else if (o[tgt] == "T") {
w[tgt] = theword(w[tgt]) + "+" + clip;
} else
w[tgt] = clip;
}
}
if (cmd == "lex") {
// Look up a lexical item; add it to the clipboard
var item = Look(partz, i); i++;
clip = Lookup(item);
}
if (cmd == "cuttense" && tgt != -1) {
// Copy tense from this word to the clipboard
var ew = theword(w[tgt]);
var plus = ew.indexOf("+");
if (plus == -1) {
clip = ew;
w[tgt] = "ø";
} else {
clip = ew.substr(0, plus);
var rem = ew.substr(plus+1);
w[tgt] = ReplaceWord(w[tgt], rem);
}
t += " copying tense " + clip;
}
if (cmd == "numclip") {
// Add subject number to clipboard
clip += FindNumber();
}
if (cmd == "insert" && tgt != -1 && clip != "") {
// Insert clipboard as new word after current location
var cat = Look(partz, i); i++;
if (cat == "") cat = thehead(clip);
t += " inserting " + theword(clip);
Insert(tgt + 1, clip, cat);
}
if (cmd == "append" && clip != "") {
// Insert clipboard as new word at end
t += " appending " + theword(clip);
o.push(thehead(clip));
w.push(clip);
}
if (cmd == "prepend" && clip != "") {
// Insert clipboard as new word at beginning, i.e., just after [S
t += " prepending " + theword(clip);
Insert(1, clip, thehead(clip))
}
if (cmd == "flip" && clip != "" && tgt != "") {
// Switch two constituents
// STD word level not done
if (clip.charAt(0) == '#') {
var n = parseInt(clip.substr(1));
t += " flipping " + n + " and " + tgt;
Flip(n, tgt);
}
}
}
}
// Given a word, return its number s/p
// If it's not defined, return ""
function theNumber(wd)
{
var arg = thearg(wd);
args = arg.split(" ");
for (var i = 0; i < args.length; i++) {
if (args[i] == "s" || args[i] == "p")
return args[i];
}
return "";
}
// Find the inflection of the subject, which is stored in thearg of the word
function FindNumber() {
// Find the inflection of the subject, if any
var n = FindFirst("N|Pron");
t += " findnumber " + n + " - " + thearg(w[n]);
if (n != -1)
return theNumber(w[n]);
return "";
}
// Used by DoDefine. Apply ins > outs for each sep-separated argument in s.
function DoArgs(s, sep, ins, outs)
{
var args = s.split(sep);
var s = "";
for (var j = 0; j < args.length; j++) {
if (s != "") s += sep;
if (args[j] == ins)
s += outs;
else {
if (sep == " " && args[j].indexOf("|") != -1)
s += DoArgs(args[j], "|", ins, outs);
else
s += args[j];
}
}
return s;
}
// Apply a definition to remaining rules
function DoDefine(def, xx, i) {
var sp = def.indexOf(" ");
var eq = def.indexOf("=", sp + 1);
if (sp == -1 || eq == -1) return;
sp++;
var ins = def.substr(sp, eq - sp);
var outs = def.substr(eq + 1);
t += "<br/>Replacing " + ins + " with " + outs;
for (; i < xx.length; i++)
if (xx[i].charAt(0) != '*')
xx[i] = DoArgs(xx[i], " ", ins, outs);
}
// Generate a sentence. Uses globals o[], w[]
function GenerateS(psr, xx)
{
// Always start with a bare S
o = new Array();
o.push("S");
w = null;
// Apply phrase structure rules till we have a sentence
for (var r = 0; r < psr.length; r++) {
if (Apply(psr[r])) {
if (showpsr) t += "<br/>" + Stringize(o, w);
o = oo;
}
}
w = Lexicalize(o);
t += "<p><b>Deep structure:</b> " + Stringize(o, w);
// Apply transformations
for (var x = 0; x < xx.length; x++) {
var xform = xx[x];
if (xform.charAt(0) == '*')
t += "<br/>" + xform;
if (xform.substr(0,6) == "define") {
DoDefine(xform, xx, x + 1);
} else
Xform(xform);
}
t += "<p><b>Surface structure:</b> " + Stringize(o, w);
}
// Embed one S (o/w) within another (oo/ww) at location tgt
// Repalce o/w with the combined sentence
function Embed(oo, ww, tgt) {
var o2 = new Array();
var w2 = new Array();
for (var i = 0; i < tgt; i++) {
o2.push(oo[i]);
w2.push(ww[i]);
}
for (var i = 0; i < o.length; i++) {
o2.push(o[i]);
w2.push(w[i]);
}
for (var i = tgt + 1; i < oo.length; i++) {
o2.push(oo[i]);
w2.push(ww[i]);
}
o = o2;
w = w2;
}
// User hit the Generate button
function process()
{
//Read parameters
theform = document.theform;
var text = document.getElementById("mytext");
// Read the lexicon
var s = theform.lex.value;
lex = s.split("\n");
// Read the phrase structure rules
s = theform.psr.value;
psr = s.split("\n");
// Read the transformations
s = theform.xform.value;
xx = s.split("\n");
t = "";
embedding = false;
inf = false;
// Generate a sentence
GenerateS(psr, xx);
// Embedded sentences
emb = FindFirst("S|Sinf");
if (emb != -1) {
var oo = o;
var ww = w;
t += "<p><b>Creating embedded sentence</b>";
embedding = true;
if (oo[emb] == "Sinf") {
inf = true;
oo[emb] = "S";
}
GenerateS(psr, xx);
Embed(oo, ww, emb);
t += "<p><b>Embedded:</b> " + Stringize(o, w);
}
// Link to drawing program
var url = "http://ironcreek.net/phpsyntaxtree/?" + wordbrax(o, w);
t += '<p><a href="' + url + '" target="_blank"><b>Draw tree</b></a>';
// Final output
t = "<b>Final:</b> " + Pronounce(w) + t;
// Output
text.innerHTML = t;
}
function helpme()
{
window.open("gtghelp.html");
}
</script>
<table width="100%">
<tr><td bgcolor="#EEC25A">
<h2><br> <a href="kit.html"><img src="liltree.gif" border=0 align="absmiddle" height="53" width="60"></a> gtg</h2></td></tr>
</td></tr>
</table>
<i>This is a Javascript program which allows you to define a generative grammar. Press Generate to test, and Help for documentation.
<blockquote><span style="color:red;"><b>Warning:</b> This program is <b>in progress</b> and apt to change at any time.
</span></blockquote>
<p>Also see: <A href="markov.html">Markov generator</a>; <a href="ggg.html">Generative Grammar Gadget</a>; <a href="mg.html">Minimalism gadget</a>.
<p>—Mark Rosenfelder, 2018</i>
<hr>
<table width="100%">
<tr>
<td>
Lexicon:
<br><textarea id="lex" name="lex" rows="15" cols="30">
Q:Comp
ø:Comp
the:D
this:D::p these
that:D::p those
cat:N::p cats
dog:N::p dogs
mouse:N::p mice
man:N:m:p men
woman:N:f:p women
frog:N::p frogs
monster:N::p monsters
boy:N:m:p boys
girl:N:f:p girls
past:T:
pres:T:
not:Neg:
must:Modal:
can:Modal:
have:Perf::pres has past had pastp had ing having en had
be:Prog::pres is presp are past was pastp were ing being en been
do:V:NP:pres does past did pastp did ing doing en done
sit:V:PP:pres sits past sat pastp sat ing sitting en sat
sleep:V:pres sleeps past slept pastp slept ing sleeping en slept
hate:V:NP:pres hates past hated pastp hated ing hating en hated
love:V:NP:pres loves past loved pastp loved ing loving en loved
chase:V:NP:pres chases past chased pastp chased ing chasing en chased
give:V:NP NP:pres gives past gave pastp gave ing giving en given
think:V:S:pres thinks past thought pastp thought ing thinking en thought
know:V:S:pres knows past knew pastp knew ing knowing en known
want:V:Sinf:pres wants past wanted pastp wanted ing wanting en wanted
put:V:NP PP:pres puts past put pastp put ing putting en put
care:V::pres cares past cared pastp cared ing caring en cared
by:P
near:P
to:P
big:A
little:A
nice:A
nasty:A
beautiful:A
ugly:A
happy:A
sad:A
who:Pron::
he:Pron:m:acc him p they pacc them
she:Pron:f:acc her p they pacc them
everyone:Pron::
someone:Pron::
</textarea>
</td>
<td width="20px"> </td>
<td>
Phrase structure:
<br><textarea id="psr" name="psr" rows="15" cols="30">
S=Comp TP
TP=NP T VP
VP=Modal VP=?
VP=Perf VP=?
VP=Prog VP=?
VP=V (NP)|V NP PP|V S|V Sinf
PP=P NP
NP=D ?A N|Pron
</textarea>
</td>
<td width="20px"> </td>
<td>
Transformations:
<br><textarea id="xform" name="xform" rows="15" cols="55">
define Aux=Modal|Perf|Prog|Pass
* suppress questions in subclauses
sub lex ø if word Q paste
* plural form of determiners
start find next N copy num find previous D paste find next N loop
* negative
maybe if Aux lex not insert Neg
maybe if no Aux find T lex not insert Neg
* passive
checkif V [NP [NP
yes transform V [NP [NP into »be:Pass [VP 0 1 [PP »by 2 ] ] end subject copy object flip
no transform V [NP into »be:Pass [VP 0 [PP »by 1 ] ] end subject copy object flip
* wh-question
main object ifword who cut prepend transform Comp into »Q
main subject ifword who transform Comp into »ø
* dative movement
maybe transform [NP [NP into 1 [PP »to 0 ]
* question formation
if word Q transform [NP T into 1 0
if word Q find Aux cut find T paste
* object forms of pronouns
find V start find next Pron inflect acc loop
if word inf find V find last Pron inflect acc
* passive inflection
if Pass find next V inflect en
* progressive
if Prog find next V|Pass inflect ing
* perfect
if Perf find next V|Pass|Prog inflect en
* Infinitive S: suppress modal, add to
if word inf find Modal cut
if word inf find T lex to insert
* Do support
if no Aux lex do if Neg find T paste
if no Aux lex do if no Neg if word Q find T paste
* verbal inflection
if no word inf if T cuttense numclip find V|Aux inflect clip
</textarea>
</td>
<!--
:Q=[NP T=1+Aux 0
Prog:+:V:ing:Progressive
Perf:+:V|Aux:en:Perfect
T:≠:V|Aux:^do:Do-Support
T:+:Neg≠Aux:^do:Neg Do-Support
T:+:V|Aux:TENSE:Verbal Inflection
Neg:±:T|Aux:+n't:Negative Contraction
* tag question
if no word Q lex tag append QQ
if QQ transform QQ into [S 0 T »someone ]
if QQ find Modal|Perf|Prog copy find next T paste
if QQ if no Modal|Perf|Prog find T find next T lex do paste
this doesn't even work yet! 3 cases
NP ø Aux, Aux he? -- copied correctly
NP gave, didn't he? -- do is inserted, but not inflected right
NP did not give, did he? -- ditto
PLUS we don't handle the pronoun
PLUS we don't handle the "n't"
We really need to handle m/f so we can do a) reflexives; b) tag Q; c) French.
-->
<td>
<p><input type="button" value="Generate" onClick="process();">
<p><input type="button" value="Help me!" onClick="helpme();">
</td>
</tr></table>
<hr>
<h3>Output</h3>
<br><div id="mytext"> </div>
</form>
<hr>
<center><A HREF="default.html"><img src="homeg.gif" border=0 alt="Home"></A></center>
</body>
</html>