func writeTerminals(gSymbols *symbols.Symbols, cfg config.Config) { buf := new(bytes.Buffer) for _, t := range gSymbols.ListTerminals() { fmt.Fprintf(buf, "%s\n", t) } io.WriteFile(path.Join(cfg.OutDir(), "terminals.txt"), buf.Bytes()) }
// TODO: optimise loop // g is a BNF grammar. Items returns the sets of Items of the grammar g. func GetItemSets(g *ast.Grammar, s *symbols.Symbols, firstSets *first.FirstSets) *ItemSets { C := &ItemSets{ sets: []*ItemSet{InitialItemSet(g, s, firstSets).Closure()}, } symbols := s.List() included := -1 for again := true; again; { again = false for i, I := range C.sets { if i > included { for _, X := range symbols { gto := I.Goto(X) if gto.Size() > 0 { idx := C.GetIndex(gto) if idx == -1 { C.sets, again = append(C.sets, gto), true idx = len(C.sets) - 1 gto.SetNo = idx } I.AddTransition(X, idx) } } included = i } } } return C }
func getGotoRowData(itemSet *items.ItemSet, sym *symbols.Symbols) []gotoRowElement { row := make([]gotoRowElement, sym.NumNTSymbols()) for i, nt := range sym.NTList() { row[i].NT = nt row[i].State = itemSet.NextSetIndex(nt) } return row }
func getGotoTableData(itemSets *items.ItemSets, sym *symbols.Symbols) *gotoTableData { data := &gotoTableData{ NumNTSymbols: sym.NumNTSymbols(), Rows: make([]string, itemSets.Size()), } for i, set := range itemSets.List() { data.Rows[i] = genGotoRow(set, sym) } return data }
func getProdsTab(header string, prods ast.SyntaxProdList, symbols *symbols.Symbols, itemsets *items.ItemSets, tokMap *token.TokenMap) *prodsTabData { data := &prodsTabData{ Header: header, ProdTab: make([]prodTabEntry, len(prods)), } for i, prod := range prods { data.ProdTab[i].String = fmt.Sprintf("`%s`", prod.String()) data.ProdTab[i].Id = prod.Id data.ProdTab[i].NTType = symbols.NTType(prod.Id) if prod.Body.Symbols[0].SymbolString() == "empty" { data.ProdTab[i].NumSymbols = 0 data.ProdTab[i].ReduceFunc = fmt.Sprintf("return nil, nil") } else { data.ProdTab[i].NumSymbols = len(prod.Body.Symbols) switch { case prod.Body.SDT != "": data.ProdTab[i].ReduceFunc = fmt.Sprintf("return %s", prod.Body.SDT) default: data.ProdTab[i].ReduceFunc = fmt.Sprintf("return X[0], nil") } } } return data }
//Returns the FirstSets of the Grammar. func GetFirstSets(g *ast.Grammar, symbols *symbols.Symbols) *FirstSets { firstSets := &FirstSets{ firstSets: make(map[string]SymbolSet), symbols: symbols, } if g.SyntaxPart == nil { return firstSets } for i, again := 1, true; again; i++ { again = false for _, prod := range g.SyntaxPart.ProdList { switch { case len(prod.Body.Symbols) == 0: if firstSets.AddToken(prod.Id, EMPTY) { again = true } case symbols.IsTerminal(prod.Body.Symbols[0].SymbolString()): if firstSets.AddToken(prod.Id, prod.Body.Symbols[0].SymbolString()) { again = true } default: first := FirstS(firstSets, stringList(prod.Body.Symbols)) if !first.Equal(firstSets.GetSet(prod.Id)) { if firstSets.AddSet(prod.Id, first) { again = true } } } } } return firstSets }
func getParserData(pkg string, prods ast.SyntaxProdList, itemSets *items.ItemSets, symbols *symbols.Symbols, cfg config.Config) *parserData { return &parserData{ Debug: cfg.DebugParser(), ErrorImport: path.Join(pkg, "errors"), TokenImport: path.Join(pkg, "token"), NumProductions: len(prods), NumStates: itemSets.Size(), NumSymbols: symbols.NumSymbols(), } }