mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-23 03:32:51 -06:00
gfse: initial support for module extension
There is a new way to create a new grammar based on an existing grammar: by extending it. (It is also possible to clone an existing grammar, a before.)
This commit is contained in:
@@ -24,7 +24,7 @@ function upload(g) {
|
|||||||
[hidden(g.basename+".gf",show_abstract(g))])
|
[hidden(g.basename+".gf",show_abstract(g))])
|
||||||
for(var i in g.concretes)
|
for(var i in g.concretes)
|
||||||
form.appendChild(hidden(g.basename+g.concretes[i].langcode+".gf",
|
form.appendChild(hidden(g.basename+g.concretes[i].langcode+".gf",
|
||||||
show_concrete(g.basename)(g.concretes[i])));
|
show_concrete(g)(g.concretes[i])));
|
||||||
editor.appendChild(form);
|
editor.appendChild(form);
|
||||||
form.submit();
|
form.submit();
|
||||||
form.parentNode.removeChild(form);
|
form.parentNode.removeChild(form);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ function upload(g) {
|
|||||||
var cname=g.basename+g.concretes[i].langcode+".gf";
|
var cname=g.basename+g.concretes[i].langcode+".gf";
|
||||||
//files.push(cname);
|
//files.push(cname);
|
||||||
form.appendChild(hidden(cname,
|
form.appendChild(hidden(cname,
|
||||||
show_concrete(g.basename)(g.concretes[i])));
|
show_concrete(g)(g.concretes[i])));
|
||||||
}
|
}
|
||||||
editor.appendChild(form);
|
editor.appendChild(form);
|
||||||
form.submit();
|
form.submit();
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ div#file, pre.plain { background: white; padding: 0.6ex; }
|
|||||||
img.cloud, img.right, div.right, div.modtime { float: right; }
|
img.cloud, img.right, div.right, div.modtime { float: right; }
|
||||||
.modtime { color: #999; white-space: nowrap; }
|
.modtime { color: #999; white-space: nowrap; }
|
||||||
|
|
||||||
|
table.grammar_list { border-collapse: collapse; margin-left: 1.0em; }
|
||||||
|
table.grammar_list td { padding: 0.4ex 0.25em; }
|
||||||
|
|
||||||
div.namebar { background: #9df; }
|
div.namebar { background: #9df; }
|
||||||
div.namebar table { width: 100%; }
|
div.namebar table { width: 100%; }
|
||||||
.namebar h3, .home h3 { margin: 0; color: #009; }
|
.namebar h3, .home h3 { margin: 0; color: #009; }
|
||||||
@@ -45,7 +48,8 @@ div.template:hover
|
|||||||
|
|
||||||
.editable:hover, .deletable:hover { background: #ff9; }
|
.editable:hover, .deletable:hover { background: #ff9; }
|
||||||
|
|
||||||
.extensible:hover .more,.editable:hover > .edit ,.deletable:hover > .delete
|
.extensible:hover .more,.editable:hover > .edit ,.deletable:hover > .delete,
|
||||||
|
tr.deletable:hover .delete
|
||||||
{ visibility: visible; }
|
{ visibility: visible; }
|
||||||
|
|
||||||
.more { color: green; }
|
.more { color: green; }
|
||||||
|
|||||||
@@ -35,24 +35,29 @@ function draw_grammar_list() {
|
|||||||
insertAfter(cloud_download,cloud_upload);
|
insertAfter(cloud_download,cloud_upload);
|
||||||
}
|
}
|
||||||
editor.appendChild(home)
|
editor.appendChild(home)
|
||||||
var gs=ul([]);
|
|
||||||
function del(i) { return function () { delete_grammar(i); } }
|
function del(i) { return function () { delete_grammar(i); } }
|
||||||
function clone(i) { return function (g,b) { clone_grammar(i); } }
|
function clone(i) { return function (g,b) { clone_grammar(i); } }
|
||||||
for(var i=0;i<local.count;i++) {
|
function new_extension(i) { return function (g,b) { new_grammar([g]) }}
|
||||||
var grammar=local.get(i,null);
|
function item(i,grammar) {
|
||||||
if(grammar && grammar.basename) {
|
var link=a(jsurl("open_grammar("+i+")"),[text(grammar.basename)]);
|
||||||
var link=a(jsurl("open_grammar("+i+")"),[text(grammar.basename)]);
|
return node("tr",{"class":"extensible deletable"},
|
||||||
gs.appendChild(
|
[td(delete_button(del(i),"Delete this grammar")),
|
||||||
node("li",{"class":"extensible"},
|
td(link),
|
||||||
[deletable(del(i),link,"Delete this grammar"),
|
td(more(grammar,clone(i),"Clone this grammar")),
|
||||||
more(grammar,clone(i),"Clone this grammar")]))
|
td(more(grammar,new_extension(i),"Create an extension of this grammar"))])
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(local.get("count",null)==null)
|
if(local.get("count",null)==null)
|
||||||
home.appendChild(text("You have not created any grammars yet."));
|
home.appendChild(text("You have not created any grammars yet."));
|
||||||
else if(local.count==0)
|
else if(local.count==0)
|
||||||
home.appendChild(text("Your grammar list is empty."));
|
home.appendChild(text("Your grammar list is empty."));
|
||||||
home.appendChild(gs);
|
else {
|
||||||
|
var rows=[];
|
||||||
|
for(var i=0;i<local.count;i++) {
|
||||||
|
var grammar=local.get(i,null);
|
||||||
|
if(grammar && grammar.basename) rows.push(item(i,grammar))
|
||||||
|
}
|
||||||
|
home.appendChild(node("table",{"class":"grammar_list"},rows));
|
||||||
|
}
|
||||||
|
|
||||||
home.appendChild(
|
home.appendChild(
|
||||||
ul([li([a(jsurl("new_grammar()"),[text("New grammar")])])]));
|
ul([li([a(jsurl("new_grammar()"),[text("New grammar")])])]));
|
||||||
@@ -60,13 +65,31 @@ function draw_grammar_list() {
|
|||||||
home.appendChild(empty_id("div","sharing"));
|
home.appendChild(empty_id("div","sharing"));
|
||||||
}
|
}
|
||||||
|
|
||||||
function new_grammar() {
|
function new_grammar(gs) {
|
||||||
|
gs=gs || [];
|
||||||
var g={basename:"Unnamed",
|
var g={basename:"Unnamed",
|
||||||
|
extends:gs.map(function(g){return g.basename}),
|
||||||
|
// check that "Unnamed" is not in exts !!
|
||||||
abstract:{cats:[],funs:[]},
|
abstract:{cats:[],funs:[]},
|
||||||
concretes:[]}
|
concretes:empty_concretes_extending(gs)}
|
||||||
edit_grammar(g);
|
edit_grammar(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function empty_concretes_extending(gs) {
|
||||||
|
var concs=[]
|
||||||
|
var langs=[];
|
||||||
|
for(var i in gs) {
|
||||||
|
var g=gs[i];
|
||||||
|
for(var ci in g.concretes) {
|
||||||
|
var conc=g.concretes[ci];
|
||||||
|
var code=conc.langcode;
|
||||||
|
if(!langs[code])
|
||||||
|
langs[code]=true,concs.push(new_concrete(code))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return concs
|
||||||
|
}
|
||||||
|
|
||||||
function remove_local_grammar(i) {
|
function remove_local_grammar(i) {
|
||||||
local.remove(i);
|
local.remove(i);
|
||||||
while(local.count>0 && !local.get(local.count-1))
|
while(local.count>0 && !local.get(local.count-1))
|
||||||
@@ -291,6 +314,14 @@ function draw_startcat(g) {
|
|||||||
return indent([kw("flags startcat"),sep(" = "),m]);
|
return indent([kw("flags startcat"),sep(" = "),m]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function draw_extends(exts) {
|
||||||
|
var kw_extends=kw("extends ")
|
||||||
|
kw_extends.title="This grammar is an extension of the grammars listed here."
|
||||||
|
return exts && exts.length>0
|
||||||
|
? indent([kw_extends,ident(exts.join(", "))])
|
||||||
|
: text("")
|
||||||
|
}
|
||||||
|
|
||||||
function draw_abstract(g) {
|
function draw_abstract(g) {
|
||||||
var kw_cat = kw("cat");
|
var kw_cat = kw("cat");
|
||||||
kw_cat.title = "The categories (nonterminals) of the grammar are enumerated here. [C.3.2]";
|
kw_cat.title = "The categories (nonterminals) of the grammar are enumerated here. [C.3.2]";
|
||||||
@@ -307,6 +338,7 @@ function draw_abstract(g) {
|
|||||||
return div_id("file",
|
return div_id("file",
|
||||||
[kw("abstract "),ident(g.basename),sep(" = "),
|
[kw("abstract "),ident(g.basename),sep(" = "),
|
||||||
draw_timestamp(g.abstract),
|
draw_timestamp(g.abstract),
|
||||||
|
draw_extends(g.extends),
|
||||||
flags,
|
flags,
|
||||||
indent([extensible([kw_cat,
|
indent([extensible([kw_cat,
|
||||||
indent(draw_cats(g))]),
|
indent(draw_cats(g))]),
|
||||||
@@ -352,21 +384,27 @@ function rename_cat(g,el,cat) {
|
|||||||
string_editor(el,cat,ren);
|
string_editor(el,cat,ren);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function duplicated(g,kind,orig) {
|
||||||
|
return orig==g.basename
|
||||||
|
? "Same "+kind+" defined twice in this module"
|
||||||
|
: "Same "+kind+" already defined in "+orig
|
||||||
|
}
|
||||||
|
|
||||||
function draw_cats(g) {
|
function draw_cats(g) {
|
||||||
var cs=g.abstract.cats;
|
var cs=g.abstract.cats;
|
||||||
var es=[];
|
var es=[];
|
||||||
var defined={};
|
var defined=inherited_cats(g);
|
||||||
function eident(cat) {
|
function eident(cat) {
|
||||||
function ren(g,el) { rename_cat(g,el,cat); }
|
function ren(g,el) { rename_cat(g,el,cat); }
|
||||||
return editable("span",ident(cat),g,ren,"Rename category");
|
return editable("span",ident(cat),g,ren,"Rename category");
|
||||||
}
|
}
|
||||||
function check(cat,el) {
|
function check(cat,el) {
|
||||||
return ifError(defined[cat],"Same category named twice",el);
|
return ifError(defined[cat],duplicated(g,"category",defined[cat]),el);
|
||||||
}
|
}
|
||||||
function del(i) { return function() { delete_cat(g,i); }}
|
function del(i) { return function() { delete_cat(g,i); }}
|
||||||
for(var i in cs) {
|
for(var i in cs) {
|
||||||
es.push(deletable(del(i),check(cs[i],eident(cs[i])),"Delete this category"));
|
es.push(deletable(del(i),check(cs[i],eident(cs[i])),"Delete this category"));
|
||||||
defined[cs[i]]=true;
|
defined[cs[i]]=g.basename;
|
||||||
es.push(sep("; "));
|
es.push(sep("; "));
|
||||||
}
|
}
|
||||||
es.push(more(g,add_cat,"Add more categories"));
|
es.push(more(g,add_cat,"Add more categories"));
|
||||||
@@ -419,24 +457,24 @@ function draw_funs(g) {
|
|||||||
var funs=g.abstract.funs;
|
var funs=g.abstract.funs;
|
||||||
var es=[];
|
var es=[];
|
||||||
var dc=defined_cats(g);
|
var dc=defined_cats(g);
|
||||||
var df={};
|
var df=inherited_funs(g);
|
||||||
function del(i) { return function() { delete_fun(g,i); }}
|
function del(i) { return function() { delete_fun(g,i); }}
|
||||||
function draw_efun(i,df) {
|
function draw_efun(i,df) {
|
||||||
return editable("span",draw_fun(funs[i],dc,df),g,edit_fun(i),"Edit this function");
|
return editable("span",draw_fun(g,funs[i],dc,df),g,edit_fun(i),"Edit this function");
|
||||||
}
|
}
|
||||||
for(var i in funs) {
|
for(var i in funs) {
|
||||||
es.push(node_sortable("fun",funs[i].name,[deletable(del(i),draw_efun(i,df),"Delete this function")]));
|
es.push(node_sortable("fun",funs[i].name,[deletable(del(i),draw_efun(i,df),"Delete this function")]));
|
||||||
df[funs[i].name]=true;
|
df[funs[i].name]=g.basename;
|
||||||
}
|
}
|
||||||
es.push(more(g,add_fun,"Add a new function"));
|
es.push(more(g,add_fun,"Add a new function"));
|
||||||
return es;
|
return es;
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw_fun(fun,dc,df) {
|
function draw_fun(g,fun,dc,df) {
|
||||||
function check(el) {
|
function check(el) {
|
||||||
return ifError(dc[fun.name],
|
return ifError(dc[fun.name],
|
||||||
"Function names must be distinct from category names",
|
"Function names must be distinct from category names",
|
||||||
ifError(df[fun.name],"Same function defined twice",el));
|
ifError(df[fun.name],duplicated(g,"function",df[fun.name]),el));
|
||||||
}
|
}
|
||||||
return node("span",{},
|
return node("span",{},
|
||||||
[check(ident(fun.name)),sep(" : "),draw_type(fun.type,dc)]);
|
[check(ident(fun.name)),sep(" : "),draw_type(fun.type,dc)]);
|
||||||
@@ -496,6 +534,7 @@ function draw_concrete(g,i) {
|
|||||||
edit_langcode,"Change language"),
|
edit_langcode,"Change language"),
|
||||||
kw(" of "),ident(g.basename),sep(" = "),
|
kw(" of "),ident(g.basename),sep(" = "),
|
||||||
draw_timestamp(conc),
|
draw_timestamp(conc),
|
||||||
|
draw_extends((g.extends || []).map(conc_extends(conc))),
|
||||||
indent([extensible([kw("open "),draw_opens(g,i)])]),
|
indent([extensible([kw("open "),draw_opens(g,i)])]),
|
||||||
indent([kw_lincat,draw_lincats(g,i)]),
|
indent([kw_lincat,draw_lincats(g,i)]),
|
||||||
indent([kw_lin,draw_lins(g,i)]),
|
indent([kw_lin,draw_lins(g,i)]),
|
||||||
@@ -658,7 +697,7 @@ function draw_lincats(g,i) {
|
|||||||
return node("span",{"class":cls},
|
return node("span",{"class":cls},
|
||||||
[ident(c.cat),sep(" = "),t]);
|
[ident(c.cat),sep(" = "),t]);
|
||||||
}
|
}
|
||||||
var dc=defined_cats(g);
|
var dc=locally_defined_cats(g,{});
|
||||||
function draw_lincat(c) {
|
function draw_lincat(c) {
|
||||||
var cat=c.cat;
|
var cat=c.cat;
|
||||||
var err=!dc[cat];
|
var err=!dc[cat];
|
||||||
@@ -821,7 +860,7 @@ function draw_lins(g,ci) {
|
|||||||
l.push(t);
|
l.push(t);
|
||||||
return node("span",{"class":cls},l);
|
return node("span",{"class":cls},l);
|
||||||
}
|
}
|
||||||
var df=defined_funs(g);
|
var df=locally_defined_funs(g,{});
|
||||||
function draw_lin(f) {
|
function draw_lin(f) {
|
||||||
var fun=f.fun;
|
var fun=f.fun;
|
||||||
var err= !df[fun];
|
var err= !df[fun];
|
||||||
@@ -852,6 +891,42 @@ function draw_lins(g,ci) {
|
|||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
function defined_cats(g) {
|
||||||
|
var grammar_byname=cached_grammar_byname();
|
||||||
|
var igs=(g.extends || []).map(grammar_byname)
|
||||||
|
return all_defined_cats(g,igs)
|
||||||
|
}
|
||||||
|
|
||||||
|
function inherited_cats(g) {
|
||||||
|
var grammar_byname=cached_grammar_byname();
|
||||||
|
var igs=(g.extends || []).map(grammar_byname)
|
||||||
|
return all_inherited_cats(igs,{})
|
||||||
|
}
|
||||||
|
|
||||||
|
function defined_funs(g) {
|
||||||
|
var grammar_byname=cached_grammar_byname();
|
||||||
|
var igs=(g.extends || []).map(grammar_byname)
|
||||||
|
return all_defined_funs(g,igs)
|
||||||
|
}
|
||||||
|
|
||||||
|
function inherited_funs(g) {
|
||||||
|
var grammar_byname=cached_grammar_byname();
|
||||||
|
var igs=(g.extends || []).map(grammar_byname)
|
||||||
|
return all_inherited_funs(igs,{})
|
||||||
|
}
|
||||||
|
|
||||||
|
function cached_grammar_byname() {
|
||||||
|
var gix={};
|
||||||
|
for(var i=0;i<local.count;i++) {
|
||||||
|
var g=local.get(i,null);
|
||||||
|
if(g) gix[g.basename]=g; // basenames are not necessarily unique!!
|
||||||
|
}
|
||||||
|
function grammar_byname(name) { return gix[name]; }
|
||||||
|
return grammar_byname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
function find_langcode(concs,langcode) {
|
function find_langcode(concs,langcode) {
|
||||||
for(var ci in concs)
|
for(var ci in concs)
|
||||||
if(concs[ci].langcode==langcode)
|
if(concs[ci].langcode==langcode)
|
||||||
@@ -1030,11 +1105,16 @@ function edit_button(action,hint) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function deletable(del,el,hint) {
|
function deletable(del,el,hint) {
|
||||||
var b=node("span",{"class":"delete",title:hint || "Delete"},[text("×")])
|
var b=delete_button(del,hint)
|
||||||
b.onclick=del;
|
|
||||||
return node("span",{"class":"deletable"},[b,el])
|
return node("span",{"class":"deletable"},[b,el])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function delete_button(action,hint) {
|
||||||
|
var b=node("span",{"class":"delete",title:hint || "Delete"},[text("×")])
|
||||||
|
b.onclick=action;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
function touch_edit() {
|
function touch_edit() {
|
||||||
var b=node("input",{type:"checkbox"},[]);
|
var b=node("input",{type:"checkbox"},[]);
|
||||||
function touch() {
|
function touch() {
|
||||||
|
|||||||
@@ -2,20 +2,25 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
type Id = String -- all sorts of identifiers
|
type Id = String -- all sorts of identifiers
|
||||||
|
type ModId = Id -- module name
|
||||||
type Cat = Id -- category name
|
type Cat = Id -- category name
|
||||||
|
type FunId = Id -- function name
|
||||||
type Type = [Cat] -- [Cat_1,...,Cat_n] means Cat_1 -> ... -> Cat_n
|
type Type = [Cat] -- [Cat_1,...,Cat_n] means Cat_1 -> ... -> Cat_n
|
||||||
|
|
||||||
type Grammar = { basename: Id, abstract : Abstract, concretes : [Concrete] }
|
type Grammar = { basename: ModId,
|
||||||
|
extends: [ModId],
|
||||||
|
abstract: Abstract,
|
||||||
|
concretes: [Concrete] }
|
||||||
|
|
||||||
type Abstract = { startcat: Cat, cats : [Cat], funs : [ Fun ] }
|
type Abstract = { startcat: Cat, cats: [Cat], funs: [Fun] }
|
||||||
type Fun = { name:Id, type : Type }
|
type Fun = { name: FunId, type: Type }
|
||||||
|
|
||||||
type Concrete = { langcode:Id,
|
type Concrete = { langcode: Id,
|
||||||
opens:[Id],
|
opens: [ModId],
|
||||||
params: [{name:Id, rhs:String}],
|
params: [{name: Id, rhs: String}],
|
||||||
lincats : [{ cat:Cat, type:Term}],
|
lincats : [{ cat: Cat, type: Term}],
|
||||||
opers: [{name:Lhs, rhs:Term}],
|
opers: [{name: Lhs, rhs: Term}],
|
||||||
lins: [{fun:Id, args:[Id], lin:Term}]
|
lins: [{fun: FunId, args: [Id], lin: Term}]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -24,24 +29,42 @@ type Lhs = String -- name and type of oper,
|
|||||||
type Term = String -- arbitrary GF term (not parsed by the editor)
|
type Term = String -- arbitrary GF term (not parsed by the editor)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// defined_cats :: [Grammar] -> {Cat=>Bool}
|
// locally_defined_cats :: Grammar -> {Cat=>Bool} -> {Cat=>Bool} // destr upd
|
||||||
function defined_cats(g) {
|
function locally_defined_cats(g,dc) {
|
||||||
var dc={};
|
|
||||||
with(g.abstract)
|
with(g.abstract)
|
||||||
for(var i in cats) dc[cats[i]]=true;
|
for(var i in cats) dc[cats[i]]=g.basename;
|
||||||
return dc;
|
return dc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// defined_funs :: [Grammar] -> {Id=>Bool}
|
// all_defined_cats :: Grammar -> [Grammar] -> {Cat=>Bool}
|
||||||
function defined_funs(g) {
|
function all_defined_cats(g,igs) {
|
||||||
var df={};
|
return all_inherited_cats(igs,locally_defined_cats(g,{}))
|
||||||
|
}
|
||||||
|
// all_inherited_cats :: [Grammar] -> {Cat=>Bool} -> {Cat=>Bool} // destr upd
|
||||||
|
function all_inherited_cats(igs,dc) {
|
||||||
|
for(var i in igs) dc=locally_defined_cats(igs[i],dc)
|
||||||
|
return dc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// locally_defined_funs :: [Grammar] -> {FunId=>ModId} -> {Id=>ModId} // destr upd
|
||||||
|
function locally_defined_funs(g,df) {
|
||||||
with(g.abstract)
|
with(g.abstract)
|
||||||
for(var i in funs) df[funs[i].name]=true;
|
for(var i in funs) df[funs[i].name]=g.basename;
|
||||||
|
return df;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all_defined_funs :: Grammar -> [Grammar] -> {FunId=>ModId}
|
||||||
|
function all_defined_funs(g,igs) {
|
||||||
|
return all_inherited_funs(igs,locally_defined_funs(g,{}))
|
||||||
|
}
|
||||||
|
// all_inherited_funs :: [Grammar] -> {FunId=>ModId} -> {FunId=>ModId} // destr upd
|
||||||
|
function all_inherited_funs(igs,df) {
|
||||||
|
for(var i in igs) df=locally_defined_funs(igs[i],df)
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the type of a named function in the abstract syntax
|
// Return the type of a named function in the abstract syntax
|
||||||
// function_type :: Grammar -> Id -> Type
|
// function_type :: Grammar -> FunId -> Type
|
||||||
function function_type(g,fun) {
|
function function_type(g,fun) {
|
||||||
with(g.abstract)
|
with(g.abstract)
|
||||||
for(var i in funs) if(funs[i].name==fun) return funs[i].type
|
for(var i in funs) if(funs[i].name==fun) return funs[i].type
|
||||||
@@ -187,7 +210,7 @@ function parse_oper(s) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- Print as plain text (normal GF concrete syntax) ---------------------- */
|
/* --- Print as plain text (normal GF source syntax) ------------------------- */
|
||||||
|
|
||||||
function show_type(t) {
|
function show_type(t) {
|
||||||
var s="";
|
var s="";
|
||||||
@@ -209,7 +232,9 @@ function show_grammar(g) {
|
|||||||
function show_abstract(g) {
|
function show_abstract(g) {
|
||||||
// var startcat= g.abstract.cats.length==1 ? g.abstract.cats[0] : g.abstract.startcat;
|
// var startcat= g.abstract.cats.length==1 ? g.abstract.cats[0] : g.abstract.startcat;
|
||||||
var startcat= g.abstract.startcat || g.abstract.cats[0];
|
var startcat= g.abstract.startcat || g.abstract.cats[0];
|
||||||
return "abstract "+g.basename+" = {\n\n"
|
return "abstract "+g.basename+" = "
|
||||||
|
+show_extends(g.extends)
|
||||||
|
+"{\n\n"
|
||||||
+"flags coding = utf8 ;\n\n"
|
+"flags coding = utf8 ;\n\n"
|
||||||
+show_startcat(startcat)
|
+show_startcat(startcat)
|
||||||
+show_cats(g.abstract.cats)
|
+show_cats(g.abstract.cats)
|
||||||
@@ -217,6 +242,10 @@ function show_abstract(g) {
|
|||||||
+"}\n";
|
+"}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function show_extends(exts) {
|
||||||
|
return exts && exts.length>0 ? exts.join(", ")+" ** " : "";
|
||||||
|
}
|
||||||
|
|
||||||
function show_startcat(startcat) {
|
function show_startcat(startcat) {
|
||||||
return startcat ? "flags startcat = "+startcat+";\n\n" : "";
|
return startcat ? "flags startcat = "+startcat+";\n\n" : "";
|
||||||
}
|
}
|
||||||
@@ -228,15 +257,18 @@ function show_cats(cats) {
|
|||||||
function show_funs(funs) { return show_list("fun",show_fun,funs); }
|
function show_funs(funs) { return show_list("fun",show_fun,funs); }
|
||||||
|
|
||||||
function show_concretes(g) {
|
function show_concretes(g) {
|
||||||
return map(show_concrete(g.basename),g.concretes).join("\n\n");
|
return map(show_concrete(g),g.concretes).join("\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
function show_concrete(basename) {
|
function conc_extends(conc) { return function(m) { return m+conc.langcode; }}
|
||||||
|
|
||||||
|
function show_concrete(g) {
|
||||||
return function(conc) {
|
return function(conc) {
|
||||||
return "--# -path=.:present\n"
|
return "--# -path=.:present\n"
|
||||||
+ "concrete "+basename+conc.langcode+" of "+basename+" ="
|
+ "concrete "+g.basename+conc.langcode+" of "+g.basename+" = "
|
||||||
|
+show_extends((g.extends || []).map(conc_extends(conc)))
|
||||||
+show_opens(conc.opens)
|
+show_opens(conc.opens)
|
||||||
+" {\n\nflags coding = utf8 ;\n\n"
|
+"{\n\nflags coding = utf8 ;\n\n"
|
||||||
+show_params(conc.params)
|
+show_params(conc.params)
|
||||||
+show_lincats(conc.lincats)
|
+show_lincats(conc.lincats)
|
||||||
+show_opers(conc.opers)
|
+show_opers(conc.opers)
|
||||||
@@ -252,7 +284,7 @@ function show_list(kw,show1,list) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function show_opens(opens) {
|
function show_opens(opens) {
|
||||||
return opens && opens.length>0 ? "\n\nopen "+opens.join(", ")+" in" : ""
|
return opens && opens.length>0 ? "\n\nopen "+opens.join(", ")+" in " : ""
|
||||||
}
|
}
|
||||||
|
|
||||||
function show_params(params) { return show_list("param",show_param,params); }
|
function show_params(params) { return show_list("param",show_param,params); }
|
||||||
|
|||||||
Reference in New Issue
Block a user