Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit740d389

Browse files
committed
CFG: Del transformation: Improvement and description of steps
1 parent80a0ebd commit740d389

File tree

1 file changed

+58
-22
lines changed

1 file changed

+58
-22
lines changed

‎src/ContextFreeGrammar/ContextFreeGrammar.ts‎

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -344,21 +344,32 @@ export class ContextFreeGrammar {
344344
}
345345

346346
publicdel():ContextFreeGrammar;
347-
publicdel(step:(cfg:ContextFreeGrammar)=>void):ContextFreeGrammar;
348-
publicdel(step?:(cfg:ContextFreeGrammar)=>void):ContextFreeGrammar{
349-
constproductions=newMap<string,Production>();
347+
publicdel(step:StepCallback<ContextFreeGrammar>):ContextFreeGrammar;
348+
publicdel(step?:StepCallback<ContextFreeGrammar>):ContextFreeGrammar{
349+
constproductions=newMap<string,Array<Array<Token>>>([...this.productions].map(([nt,p])=>[nt,p.map(s=>[...s])]));
350350

351351
constnullableNonTerminals=newSet<string>(this.nullableNonTerminals());
352352
constnullNonTerminals=newSet<string>(this.nullNonTerminals(nullableNonTerminals));
353353

354-
for(const[nt,p]of[...this.productions].sort(([a,_a],[b,_b])=>sortBySymbolButFirst(a,b,this.start))){
354+
for(const[nt,p]of[...productions].sort(([a,_a],[b,_b])=>sortBySymbolButFirst(a,b,this.start))){
355+
letchangeHappened=false;
356+
letchangeDescription:string=null;
355357
if(!nullNonTerminals.has(nt)){
356-
constproduction=newArray<ReadonlyArray<Token>>();
358+
constfactoredOut=newArray<string>();
359+
constremoved=newArray<string>();
360+
letremovedEmpty=false;
361+
letproduction=newArray<Array<Token>>();
357362
for(constsofp){
358363
constsequences=newArray<Array<Token>>(newArray<Token>());
359364
for(consttokenofs){
360-
if(token.kind===TokenKind.Empty||
361-
(token.kind===TokenKind.NonTerminal&&nullNonTerminals.has(token.identifier))){
365+
if(token.kind===TokenKind.Empty){
366+
removedEmpty=true;
367+
changeHappened=true;
368+
continue;
369+
}
370+
elseif(token.kind===TokenKind.NonTerminal&&nullNonTerminals.has(token.identifier)){
371+
removed.push(token.identifier);
372+
changeHappened=true;
362373
continue;
363374
}
364375
elseif(token.kind===TokenKind.NonTerminal&&nullableNonTerminals.has(token.identifier)){
@@ -367,6 +378,8 @@ export class ContextFreeGrammar {
367378
sequences.push([...sequences[i]]);
368379
sequences[i].push(token);
369380
}
381+
factoredOut.push(token.identifier);
382+
changeHappened=true;
370383
}
371384
else{
372385
for(constsequenceofsequences){
@@ -376,21 +389,44 @@ export class ContextFreeGrammar {
376389
}
377390
production.push(...sequences.filter(s=>s.length>0));
378391
}
379-
productions.set(nt,production);
380-
step?.(newContextFreeGrammar(
381-
newSet<string>([
382-
...productions.keys(),
383-
...[...productions.values()].flatMap(p=>
384-
p.flatMap(s=>
385-
s.filter(t=>t.kind===TokenKind.NonTerminal)
386-
.map(t=>t.identifier)
387-
)
388-
)
389-
]),
390-
this.terminals,
391-
productions,
392-
this.start,
393-
));
392+
production=production.filter(a=>a.length>0);
393+
if(production.length>0){
394+
productions.set(nt,production);
395+
if(changeHappened){
396+
constchanges=newArray<string>();
397+
if(removed.length>0){
398+
changes.push(`null producing non-terminal${removed.length>1 ?"s" :""}${descriptionNaturalList(removed)} were removed`);
399+
}
400+
if(factoredOut.length>0){
401+
changes.push(`nullable non-terminal${factoredOut.length>1 ?"s" :""}${descriptionNaturalList(factoredOut)} were factored out`);
402+
}
403+
if(removedEmpty){
404+
changes.push("empty string tokens were removed");
405+
}
406+
changeDescription=`From the production of${nt},${descriptionNaturalList(changes)}.`;
407+
}
408+
}
409+
else{
410+
productions.delete(nt);
411+
changeHappened=true;
412+
changeDescription=`The non-terminal${nt} only produced the empty string, and where thus removed.`;
413+
}
414+
}
415+
else{
416+
productions.delete(nt);
417+
changeHappened=true;
418+
changeDescription=`The non-terminal${nt} only produced the empty string, and where thus removed.`;
419+
}
420+
if(changeHappened){
421+
step?.(
422+
newContextFreeGrammar(
423+
productions.keys(),
424+
this.terminals,
425+
productions,
426+
this.start,
427+
),
428+
changeDescription
429+
);
394430
}
395431
}
396432

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp