private static AltRule createSubstitution(SymbolPosition position, string substSymbolName) { var code = new CodeBody().AddIdentifier("obj"); return(AltRule.CreateInternally(position, new RhsGroup[] { RhsGroup.CreateSequence(position, RepetitionEnum.Once, new RhsSymbol(position, "obj", substSymbolName)) }, new CodeMix(CodeMix.SubstitutionComment).AddBody(code))); }
private static AltRule createAppend(SymbolPosition position, string lhsSymbolName, IEnumerable <string> elementTypeNames, params RhsSymbol[] symbols) { // if it does not exists it means we don't care about adding it IEnumerable <RhsSymbol> named_symbols = symbols.Where(it => it.ObjName != null).ToArray(); string list_obj_name; if (named_symbols.Count() == 1) { list_obj_name = "list"; } else { list_obj_name = "tuple_list"; } // since we are creating this code, the only conflict can come from symbol object names list_obj_name = Grammar.RegisterName(list_obj_name, named_symbols.Select(it => it.ObjName).ToList()); var code = new CodeBody().AddSnippet("{"); if (named_symbols.Count() == 1) { code.AddWithIdentifier(list_obj_name, ".", "Add", "(", named_symbols.Single().ObjName, ");"); } else { foreach (Tuple <RhsSymbol, int> sym_pair in named_symbols.ZipWithIndex()) { code.AddWithIdentifier(list_obj_name, ".", CodeWords.Item(sym_pair.Item2 + 1), ".", "Add", "("); code.AddIdentifier(sym_pair.Item1.ObjName); code.AddSnippet(");"); } } code.AddWithIdentifier("return", " ", list_obj_name, ";}"); return(AltRule.CreateInternally(position, new RhsGroup[] { RhsGroup.CreateSequence(position, RepetitionEnum.Once, new RhsSymbol(position, list_obj_name, lhsSymbolName)), RhsGroup.CreateSequence(position, RepetitionEnum.Once, symbols.Select(it => it.ShallowClone().SetSkip(false)).ToArray()) }, new CodeMix(CodeMix.AppendComment).AddBody(code))); }
private AltRule createSeed(SymbolPosition position, List <Production> productions, bool doubled, // should we double the seed right at the start string lhsSymbolName, IEnumerable <string> elementTypeNames, params RhsSymbol[] symbols) { RhsSymbol[] init_symbols = symbols.Where(it => !it.SkipInitially).ToArray(); var main_code = new CodeBody().AddWithIdentifier(CodeWords.New, " "); main_code.Append(makeTupleListCode(position, elementTypeNames)); main_code.AddSnippet("("); IEnumerable <CodeBody> code_lists = elementTypeNames.Select(it => new CodeBody().AddWithIdentifier(CodeWords.New, " ", CodeWords.List, "<", it, ">{")).ToList(); // purpose: to handle names in doubled seed mode Dictionary <RhsSymbol, string[]> obj_name_substs = new Dictionary <RhsSymbol, string[]>(); { IEnumerable <RhsSymbol> named_symbols = symbols.Where(it => it.ObjName != null); if (named_symbols.Any()) { foreach (Tuple <RhsSymbol, CodeBody> tuple in named_symbols.SyncZip(code_lists)) { RhsSymbol nsymbol = tuple.Item1; CodeBody lcode = tuple.Item2; bool double_sym = doubled && !nsymbol.SkipInitially; string[] name_subst = new string[double_sym ? 2 : 1]; obj_name_substs.Add(nsymbol, name_subst); // if we double the element, we have to come up with new names if (double_sym) { name_subst[0] = AutoNames.Double1 + nsymbol.ObjName + "__"; name_subst[1] = AutoNames.Double2 + nsymbol.ObjName + "__"; } else { name_subst[0] = nsymbol.ObjName; } for (int i = 0; i < (double_sym ? 2 : 1); ++i) { if (i == 1) { lcode.AddSnippet(","); } if (double_sym) { lcode.AddIdentifier(name_subst[i]); } else { lcode.AddIdentifier(nsymbol.ObjName); } } } } } foreach (Tuple <CodeBody, int> code_pair in code_lists.ZipWithIndex()) { code_pair.Item1.AddSnippet("}"); if (code_pair.Item2 > 0) { main_code.AddSnippet(","); } main_code.Append(code_pair.Item1); } main_code.AddSnippet(")"); // in case of doubled seed we have to rename the symbols // otherwise just make shallow copies without renaming // but since we already set proxy name correctly, we can use shared code for both cases var seed_symbols = new LinkedList <RhsSymbol>(); for (int i = 0; i < (doubled ? 2 : 1); ++i) { foreach (RhsSymbol sym in (i == 0 ? init_symbols : symbols)) { if (sym.ObjName == null) { seed_symbols.AddLast(sym.ShallowClone()); } else { int s_idx = (i == 1 && sym.SkipInitially) ? 0 : i; seed_symbols.AddLast(sym.Renamed(obj_name_substs[sym][s_idx])); } } } return(AltRule.CreateInternally(position, // are there any symbols for production seed_symbols.Any() ? new RhsGroup[] { RhsGroup.CreateSequence(position, RepetitionEnum.Once, seed_symbols.Select(it => it.SetSkip(false)).ToArray()) } : new RhsGroup[] { }, new CodeMix(CodeMix.SeedComment).AddBody(main_code))); }