public TypeInformation LookupType(NonTerminal nonTerminal) { return(this.LookupType(nonTerminal.Type)); }
private IEnumerable <IGrammarSymbol> CreateRHS(IList <Token> rhsTokens) { var result = new LinkedList <IGrammarSymbol>(); var stack = new Stack <KeyValuePair <Group, int> >(); Alternative alternative = null; string annotation = null; Dictionary <string, string> annotationDictionary = new Dictionary <string, string>(); for (int i = 0; i < rhsTokens.Count; i++) { Token token = rhsTokens[i]; switch (token.Kind) { case Token.TokenKind.Annotation: { annotation = token.Value; string[] split = token.Value.Split(new[] { ':' }); if (split.Count() == 2) { annotationDictionary[split[0]] = split[1]; } break; } case Token.TokenKind.Identifier: { string nameToUse = annotation != null ? annotation : token.Value; string typeToUse = token.Value; bool isTypeFromGrammar = false; if (annotationDictionary.ContainsKey("name")) { nameToUse = annotationDictionary["name"]; } if (annotationDictionary.ContainsKey("type")) { typeToUse = annotationDictionary["type"]; isTypeFromGrammar = true; } var nonterminal = new NonTerminal { Name = nameToUse, GrammarType = token.Value, Type = typeToUse, IsTypeFromGrammar = isTypeFromGrammar, Annotations = new Dictionary <string, string> (annotationDictionary) }; annotation = null; annotationDictionary.Clear(); result.AddLast(nonterminal); if (stack.Count > 0) { stack.Peek().Key.Symbols.Add(nonterminal); } break; } case Token.TokenKind.String: { var terminal = new Terminal { Value = token.Value }; result.AddLast(terminal); if (stack.Count > 0) { stack.Peek().Key.Symbols.Add(terminal); } break; } case Token.TokenKind.Lparen: { var group = new Group(); stack.Push(new KeyValuePair <Group, int>(group, i)); annotation = null; annotationDictionary.Clear(); break; } case Token.TokenKind.Rparen: { // done with the group KeyValuePair <Group, int> groupAndMarker = stack.Pop(); Group group = groupAndMarker.Key; int marker = groupAndMarker.Value; Contract.Assert(group.Symbols.Count > 0); for (int j = 0; j < group.Symbols.Count; j++) { result.RemoveLast(); } result.AddLast(group); annotation = null; annotationDictionary.Clear(); break; } case Token.TokenKind.Plus: { // done with the group IGrammarSymbol prev = result.Last.Value; result.RemoveLast(); var plus = new Plus { Symbol = prev }; result.AddLast(plus); if (stack.Count > 0) { stack.Peek().Key.Symbols.Add(plus); } annotation = null; annotationDictionary.Clear(); break; } case Token.TokenKind.Star: { // done with the group IGrammarSymbol prev = result.Last.Value; result.RemoveLast(); var star = new Star { Symbol = prev }; result.AddLast(star); if (stack.Count > 0) { stack.Peek().Key.Symbols.Add(star); } annotation = null; annotationDictionary.Clear(); break; } case Token.TokenKind.Pipe: { if (alternative == null) { string typeToUse = "string"; if (annotationDictionary.ContainsKey("type")) { typeToUse = annotationDictionary["type"]; } alternative = new Alternative { Type = typeToUse }; } var group = new Group { Symbols = result.Where(e => !(e is Alternative)).ToList() }; if (group.Symbols.Count > 0) { alternative.Symbols.Add(group); } result.Clear(); result.AddLast(alternative); Contract.Assert(result.Count == 1); annotation = null; annotationDictionary.Clear(); break; } case Token.TokenKind.Arrow: annotation = null; break; } } if (alternative != null) { var group = new Group { Symbols = result.Where(e => !(e is Alternative)).ToList() }; if (group.Symbols.Count > 0) { alternative.Symbols.Add(group); } result.Clear(); result.AddLast(alternative); } return(result); }
private void AddProductionToTypeMap(Production production) { bool isNullable = true; bool isBaseType = false; bool isEnum = false; string className; if (!production.LHS.Annotations.TryGetValue("className", out className)) { className = production.LHS.Name; } string serializedName; if (!production.LHS.Annotations.TryGetValue("serializedName", out serializedName)) { serializedName = production.LHS.Name; } string cSharpTypeName = className; if (production.RHS.Count == 1) { NonTerminal type = production.RHS[0] as NonTerminal; if (type != null && Common.IsReserved(type.GrammarType)) { if (type.GrammarType.Equals(Common.DictionaryName)) { // Dictionaries are treated as custom types if (type.Type.Equals(Common.DictionaryName)) { cSharpTypeName = "Dictionary<string, string>"; } else { cSharpTypeName = "Dictionary<string, " + type.Type + ">"; } } else { switch (type.Type) { case Common.BooleanName: cSharpTypeName = "bool"; isBaseType = true; isNullable = false; break; case Common.DictionaryName: // default to a string to string dictionary cSharpTypeName = "Dictionary<string, string>"; break; case Common.IdentifierName: cSharpTypeName = "string"; isBaseType = true; break; case Common.RegExName: cSharpTypeName = "Regex"; isBaseType = true; break; case Common.StringName: cSharpTypeName = "string"; isBaseType = true; break; case Common.NumberName: cSharpTypeName = "int"; isNullable = false; isBaseType = true; break; default: cSharpTypeName = type.Type; isBaseType = true; break; } } } if (production.RHS[0] is Alternative) { isBaseType = true; isEnum = true; isNullable = false; } } this.typeMap.Add(production.LHS.Name, new TypeInformation( className, cSharpTypeName, serializedName, isBaseType, isEnum, isNullable )); }