예제 #1
0
 public TypeInformation LookupType(NonTerminal nonTerminal)
 {
     return(this.LookupType(nonTerminal.Type));
 }
예제 #2
0
        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);
        }
예제 #3
0
        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
                                 ));
        }