Extract left factor

This commit is contained in:
cyp0633 2023-04-14 19:32:26 +08:00
parent 600200720b
commit 504332abe0
Signed by: cyp0633
GPG Key ID: CF90D09FB1FDCE45
2 changed files with 35 additions and 1 deletions

View File

@ -195,6 +195,9 @@ func ExtractLeftFactor() {
BodySize: production.BodySize - len(extendFactor),
ID: production.ID, // 可以循环利用,反正这个后面会删掉
}
if newProduction.BodySize == 0 {
newProduction.BodySymbol = []interface{}{&epsilonSymbol}
}
newSymbol.ProductionTable[index] = newProduction
}
@ -202,12 +205,18 @@ func ExtractLeftFactor() {
index := 0
// 因为 prods 是按照 ProductionTable 的顺序排列的
// 所以可以直接用一个 index 一起
for originalIndex, production := range symbol.ProductionTable {
for originalIndex := 0; originalIndex < len(symbol.ProductionTable); originalIndex++ {
if index >= len(prods) {
break
}
production := symbol.ProductionTable[originalIndex]
if !cmp.Equal(production, prods[index]) {
continue
}
// 直接删掉
symbol.ProductionTable = append(symbol.ProductionTable[:originalIndex], symbol.ProductionTable[originalIndex+1:]...)
originalIndex--
index++
}
// 添加一个 A \to \alpha A'
symbol.ProductionTable = append(symbol.ProductionTable, &Production{

View File

@ -163,14 +163,17 @@ func initLeftFactorExample() {
// productions
// S -> if E then S | if E then S else S | Other
leftFactorExample.S.ProductionTable = append(leftFactorExample.S.ProductionTable, &Production{
ID: 0,
BodySize: 4,
BodySymbol: []interface{}{&leftFactorExample.If, &leftFactorExample.E, &leftFactorExample.Then, &leftFactorExample.S},
})
leftFactorExample.S.ProductionTable = append(leftFactorExample.S.ProductionTable, &Production{
ID: 1,
BodySize: 6,
BodySymbol: []interface{}{&leftFactorExample.If, &leftFactorExample.E, &leftFactorExample.Then, &leftFactorExample.S, &leftFactorExample.Else, &leftFactorExample.S},
})
leftFactorExample.S.ProductionTable = append(leftFactorExample.S.ProductionTable, &Production{
ID: 2,
BodySize: 1,
BodySymbol: []interface{}{&leftFactorExample.Other},
})
@ -394,3 +397,25 @@ func TestBuildLL1AnalysisTable(t *testing.T) {
t.Error("F, ( = F -> ( E ) not found")
}
}
// 测试提取左因子
func TestExtractLeftFactor(t *testing.T) {
GrammarSymbolTable = []interface{}{&leftFactorExample.S, &leftFactorExample.E, &leftFactorExample.If, &leftFactorExample.Else, &leftFactorExample.Other}
RootSymbol = &leftFactorExample.S
if !leftFactorExample.S.LeftFactored() {
t.Error("TestExtractLeftFactor failed")
}
ExtractLeftFactor()
for _, symbol := range GrammarSymbolTable {
if symbol, ok := symbol.(*NonTerminalSymbol); ok {
t.Log(symbol.String())
}
}
if leftFactorExample.S.LeftFactored() {
t.Error("TestExtractLeftFactor failed")
}
}