Example #1
0
        private static SemanticInfo RegisterModelType(Type modelType)
        {
            using (new Tracer(modelType))
            {
                SemanticInfo semanticInfo = ExtractSemanticInfo(modelType);
                _modelTypeToSemanticInfoMapping.Add(modelType, semanticInfo);

                foreach (string semanticTypeName in semanticInfo.MappedSemanticTypes)
                {
                    ISet <Type> mappedModelTypes;
                    if (!_semanticTypeToModelTypesMapping.TryGetValue(semanticTypeName, out mappedModelTypes))
                    {
                        mappedModelTypes = new HashSet <Type>();
                        _semanticTypeToModelTypesMapping.Add(semanticTypeName, mappedModelTypes);
                    }
                    mappedModelTypes.Add(modelType);
                }

                if (semanticInfo.PublicSemanticTypes.Any())
                {
                    Log.Debug("Model type '{0}' has semantic type(s) '{1}'.", modelType.FullName, string.Join(" ", semanticInfo.PublicSemanticTypes));
                    foreach (KeyValuePair <string, IList <string> > kvp in semanticInfo.SemanticProperties)
                    {
                        Log.Debug("\tRegistered property '{0}' as semantic property '{1}'", kvp.Key, string.Join(" ", kvp.Value));
                    }
                }

                return(semanticInfo);
            }
        }
Example #2
0
 public ExpressionNode(IToken token)
     : base(token)
 {
     ///instanciamos el NodeInfo
     NodeInfo = new SemanticInfo();
     LoadVariableInTheStack = true;
 }
        public override void CheckSignatureSemantic(SymbolTable symbolTable, List <CompileError> errors)
        {
            SemanticInfo typeInfo;

            ///el tipo no puede estar definido
            if (symbolTable.GetDefinedTypeShallow(TypeId, out typeInfo))
            {
                errors.Add(new CompileError
                {
                    Line         = this.Line,
                    Column       = this.CharPositionInLine,
                    ErrorMessage = string.Format("Current context already contains a definition for '{0}'", TypeId),
                    Kind         = ErrorKind.Semantic
                });

                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
                return;
            }

            typeInfo = new SemanticInfo
            {
                Name        = TypeId,
                ElementKind = SymbolKind.Type,
                //Type = null,
                IsPending = true
            };

            typeInfo.Type = !(this is AliasDeclarationNode) ? typeInfo : null;

            ///insertamos el tipo en la tabla de símbolos como pendiente
            symbolTable.InsertSymbol(typeInfo);
        }
        public override void CheckSemantic(SymbolTable symbolTable, List <CompileError> errors)
        {
            ///check semantics al VarDeclarationNode
            base.CheckSemantic(symbolTable, errors);

            ///check semantics al InitExpression
            InitExpression.CheckSemantic(symbolTable, errors);

            ///si InitExpression evalúa de error este también
            if (Object.Equals(InitExpression.NodeInfo, SemanticInfo.SemanticError))
            {
                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
                return;
            }

            ///si InitExpression tiene tipo 'nil'
            if (InitExpression.NodeInfo.BuiltInType == BuiltInType.Nil)
            {
                errors.Add(new CompileError
                {
                    Line         = InitExpression.Line,
                    Column       = InitExpression.CharPositionInLine,
                    ErrorMessage = "Cannot assign nil to an implicitly-typed local variable",
                    Kind         = ErrorKind.Semantic
                });

                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
            }

            ///si no hubo error seteamos los campos necesarios
            if (!Object.Equals(NodeInfo, SemanticInfo.SemanticError))
            {
                NodeInfo.Type        = SemanticInfo.Void;
                NodeInfo.BuiltInType = BuiltInType.Void;
            }

            SemanticInfo variable = new SemanticInfo
            {
                Name        = VariableName,
                ElementKind = SymbolKind.Variable,
                BuiltInType = InitExpression.NodeInfo.BuiltInType,

                ElementsType = InitExpression.NodeInfo.ElementsType,
                Fields       = InitExpression.NodeInfo.Fields,

                Type   = InitExpression.NodeInfo.Type.Type,
                ILType = InitExpression.NodeInfo.ILType
            };

            ///seteamos el ILType del NodeInfo
            NodeInfo.ILType = InitExpression.NodeInfo.ILType;

            inferredParche = InitExpression.NodeInfo.Type;

            ///agregamos la variable a la tabla de símbolos
            symbolTable.InsertSymbol(variable);
        }
Example #5
0
        /// <summary>
        /// Gets the semantic types (and prefix mappings) for a given Model Type.
        /// </summary>
        /// <param name="modelType">The Model Type.</param>
        /// <param name="prefixMappings">The prefix mappings for the prefixes used by the types.</param>
        /// <returns>The semantic types.</returns>
        public static string[] GetSemanticTypes(Type modelType, out IDictionary <string, string> prefixMappings)
        {
            // No Tracer here to reduce trace noise.
            SemanticInfo semanticInfo = GetSemanticInfo(modelType);

            prefixMappings = semanticInfo.PrefixMappings;
            return(semanticInfo.PublicSemanticTypes.ToArray());
        }
        public override void CheckSemantic(SymbolTable symbolTable, List <CompileError> errors)
        {
            ///un type no puede ser alias de si mismo
            if (AliasId.Equals(OriginalId))
            {
                errors.Add(new CompileError
                {
                    Line         = this.Line,
                    Column       = this.CharPositionInLine,
                    ErrorMessage = "Defining a self recursive 'alias' type is not allowed",
                    Kind         = ErrorKind.Semantic
                });

                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
            }

            SemanticInfo typeInfo;

            ///el tipo del que se es alias debe existir
            if (!symbolTable.GetDefinedTypeDeep(OriginalId, out typeInfo))
            {
                errors.Add(new CompileError
                {
                    Line         = GetChild(1).Line,
                    Column       = GetChild(1).CharPositionInLine,
                    ErrorMessage = string.Format("Type '{0}' could not be found in current context", OriginalId),
                    Kind         = ErrorKind.Semantic
                });

                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
            }

            ///si no ha evaluado de error le seteamos los valores
            if (!Object.Equals(NodeInfo, SemanticInfo.SemanticError))
            {
                NodeInfo.Type        = SemanticInfo.Void;
                NodeInfo.BuiltInType = BuiltInType.Void;
            }

            SemanticInfo alias;

            symbolTable.GetDefinedTypeDeep(AliasId, out alias);
            alias.BuiltInType = typeInfo.BuiltInType;

            alias.ElementsType = typeInfo.ElementsType;
            alias.Fields       = typeInfo.Fields;

            alias.Type      = typeInfo.Type;
            alias.ILType    = typeInfo.ILType;
            alias.IsPending = false;

            //change
            NodeInfo    = SemanticInfo.Void; //me parece que el nodeinfo del aliasDeclaration tiene que ser void
            aliasParche = typeInfo;
        }
Example #7
0
        private string pop(out int val)
        {
            val = 0;
            if (mSemanticStack.Count == 0)
            {
                return("null_stack_!!!");
            }
            SemanticInfo info = mSemanticStack.Pop();

            val = info.value;
            return(info.token);
        }
Example #8
0
        public override void CheckSemantic(SymbolTable symbolTable, List <CompileError> errors)
        {
            ///check semantics al CallableDeclarationNode
            base.CheckSemantic(symbolTable, errors);

            ///si BodyExpression no evaluó de error
            if (!Object.Equals(CallableBody.NodeInfo, SemanticInfo.SemanticError))
            {
                ///el procedimiento debe retornar void
                if (!CallableBody.NodeInfo.BuiltInType.IsCompatibleWith(BuiltInType.Void))
                {
                    errors.Add(new CompileError
                    {
                        Line         = CallableBody.Line,
                        Column       = CallableBody.CharPositionInLine,
                        ErrorMessage = string.Format("Cannot implicitly convert type '{0}' to 'void'", CallableBody.NodeInfo.Type.Name),
                        Kind         = ErrorKind.Semantic
                    });

                    ///el nodo evalúa de error
                    NodeInfo = SemanticInfo.SemanticError;
                }
            }

            ///si no ha evaluado de error le seteamos los valores
            if (!Object.Equals(NodeInfo, SemanticInfo.SemanticError))
            {
                NodeInfo = new SemanticInfo
                {
                    Name        = SemanticInfo.NoName,
                    ElementKind = SymbolKind.NoSymbol,
                    Type        = SemanticInfo.Void,
                    BuiltInType = BuiltInType.Void,
                    ILType      = null
                };

                SemanticInfo arg;

                ///guardamos los ILType
                for (int i = 0; i < Parameters.Count; i++)
                {
                    symbolTable.GetDefinedTypeDeep(Parameters[i].Value, out arg);
                    ILTypes.Add(arg.Type.ILType);
                }
            }

            SemanticInfo procedure;

            ///completamos la definición del procedimiento
            symbolTable.GetDefinedCallableDeep(CallableId, out procedure);
            procedure.IsPending = false;
        }
Example #9
0
        /// <summary>
        /// Gets the semantic property names for a given Model Type and property name.
        /// </summary>
        /// <param name="modelType">The Model Type.</param>
        /// <param name="propertyName">The property name.</param>
        /// <returns>The semantic property names or <c>null</c> if no semantic property names have been registered for the given property.</returns>
        public static string[] GetSemanticPropertyNames(Type modelType, string propertyName)
        {
            // No Tracer here to reduce trace noise.
            SemanticInfo semanticInfo = GetSemanticInfo(modelType);

            IList <string> semanticPropertyNames;

            if (semanticInfo.SemanticProperties.TryGetValue(propertyName, out semanticPropertyNames))
            {
                return(semanticPropertyNames.ToArray());
            }
            return(null);
        }
        public override void CheckSemantic(SymbolTable symbolTable, List <CompileError> errors)
        {
            SemanticInfo variableInfo;

            ///chequeamos que no haya una variable con el mismo nombre
            if (symbolTable.GetDefinedVariableShallow(CallableId, out variableInfo))
            {
                errors.Add(new CompileError
                {
                    Line         = GetChild(ChildCount - 2).Line,
                    Column       = GetChild(ChildCount - 2).CharPositionInLine,
                    ErrorMessage = string.Format("There is already a definition for '{0}' in current context", CallableId),
                    Kind         = ErrorKind.Semantic
                });

                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
            }

            ///creamos el scope de la función o procedimiento
            symbolTable.InitNewScope();

            SemanticInfo param;

            ///agregamos los parámetros de la función o procedimiento al scope
            for (int i = 0; i < Parameters.Count; i++)
            {
                param = new SemanticInfo
                {
                    Name         = Parameters[i].Key,
                    ElementKind  = SymbolKind.Variable,
                    BuiltInType  = parametersType[i].BuiltInType,
                    Type         = parametersType[i],
                    ElementsType = parametersType[i].ElementsType,
                    Fields       = parametersType[i].Fields
                };

                symbolTable.InsertSymbol(param);
            }

            ///check semantics al CallableBody
            CallableBody.CheckSemantic(symbolTable, errors);

            ///destruimos el scope de la función o procedimiento
            symbolTable.CloseCurrentScope();
        }
Example #11
0
        private static SemanticInfo RegisterModelType(Type modelType)
        {
            using (new Tracer(modelType))
            {
                SemanticInfo semanticInfo = ExtractSemanticInfo(modelType);
                _modelTypeToSemanticInfoMapping.Add(modelType, semanticInfo);

                foreach (string semanticTypeName in semanticInfo.MappedSemanticTypes)
                {
                    ISet <Type> mappedModelTypes;
                    if (!_semanticTypeToModelTypesMapping.TryGetValue(semanticTypeName, out mappedModelTypes))
                    {
                        mappedModelTypes = new HashSet <Type>();
                        _semanticTypeToModelTypesMapping.Add(semanticTypeName, mappedModelTypes);
                    }
                    mappedModelTypes.Add(modelType);

                    int    entityNameSeparatorPos = semanticTypeName.LastIndexOf(':');
                    string vocabularyId           = semanticTypeName.Substring(0, entityNameSeparatorPos);
                    string entityName             = semanticTypeName.Substring(entityNameSeparatorPos + 1);

                    IList <Tuple <string, Type> > entityNameModelTypeTuples;
                    if (!_vocabularyToModelTypesMapping.TryGetValue(vocabularyId, out entityNameModelTypeTuples))
                    {
                        entityNameModelTypeTuples = new List <Tuple <string, Type> >();
                        _vocabularyToModelTypesMapping.Add(vocabularyId, entityNameModelTypeTuples);
                    }
                    entityNameModelTypeTuples.Add(new Tuple <string, Type>(entityName, modelType));
                }

                if (Log.IsDebugEnabled)
                {
                    if (semanticInfo.PublicSemanticTypes.Any())
                    {
                        Log.Debug("Model type '{0}' has semantic type(s) '{1}'.", modelType.FullName, String.Join(" ", semanticInfo.PublicSemanticTypes));
                        foreach (KeyValuePair <string, IList <string> > kvp in semanticInfo.SemanticProperties)
                        {
                            Log.Debug("\tRegistered property '{0}' as semantic property '{1}'", kvp.Key, String.Join(" ", kvp.Value));
                        }
                    }
                }

                return(semanticInfo);
            }
        }
        public override void CheckSemantic(SymbolTable symbolTable, List <CompileError> errors)
        {
            ///seteamos los campos necesarios
            NodeInfo = new SemanticInfo
            {
                BuiltInType = BuiltInType.Void,
                Type        = SemanticInfo.Void
            };

            ExpressionNode currentExpression = null;

            //check semantics a cada una de las expresiones
            for (int i = 0; i < ExpressionCount; i++)
            {
                currentExpression = ExpressionAt(i);

                ///check semantics a la currentExpression
                currentExpression.CheckSemantic(symbolTable, errors);

                ///si alguna de las expresiones evalúa de error este también
                if (Object.Equals(currentExpression.NodeInfo, SemanticInfo.SemanticError))
                {
                    ///el nodo evalúa de error
                    NodeInfo = SemanticInfo.SemanticError;
                }
            }

            ///si este no ha evaluado de error
            if (!Object.Equals(NodeInfo, SemanticInfo.SemanticError))
            {
                ///si hay mas de una expresión y ninguna tiene break
                if (ExpressionCount > 0 && !AnyExpressionContainsBreak)
                {
                    //NodeInfo.BuiltInType = currentExpression.NodeInfo.BuiltInType;
                    //NodeInfo.Type = currentExpression.NodeInfo.Type;

                    //NodeInfo.ElementsType = currentExpression.NodeInfo.ElementsType;
                    //NodeInfo.Fields = currentExpression.NodeInfo.Fields;
                    //NodeInfo.ILType = currentExpression.NodeInfo.ILType;
                    NodeInfo = currentExpression.NodeInfo;
                }
            }
        }
Example #13
0
        // <statblock> ::= { <statementstar> } | <statement> | e
        protected bool NTF_StatBlock(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, Lexer.Token.TokenType.OpenBrace, "if", "for", "cin", "cout", "return", Lexer.Token.TokenType.Identifier,
                "else", "fi", Lexer.Token.TokenType.Semicolon);

            if (lookahead.Type == Lexer.Token.TokenType.OpenBrace)
            {
                error |= !Match(p, Lexer.Token.TokenType.OpenBrace);
                error |= !NTF_StatementStar(p, si);
                error |= !Match(p, Lexer.Token.TokenType.CloseBrace);

                if (!error && p == 1)
                    Log(LogType.Parse, "<statblock> ::= { <statementstar> }");
            }
            // first(<statementstar>)
            else if (lookahead.Value == "if" || lookahead.Value == "for" || lookahead.Value == "cin" || lookahead.Value == "cout"
                || lookahead.Value == "return" || lookahead.Type == Lexer.Token.TokenType.Identifier)
            {
                error |= !NTF_Statement(p, si);

                if (!error && p == 1)
                    Log(LogType.Parse, "<statblock> ::= <statement>");
            }
            // follow(<statblock>)=else+fi+;
            else if (lookahead.Value == "else" || lookahead.Value == "fi" || lookahead.Type == Lexer.Token.TokenType.Semicolon)
            {
                if (p == 1)
                    Log(LogType.Parse, "<statblock> ::= e");
            }
            else
                error = true;

            return !error;
        }
Example #14
0
        private void _createFromOldFormat(XElement elementXML)
        {
            Debug.Assert(elementXML.Attribute(Consts.AttWordId) != null);
            Id = elementXML.Attribute(Consts.AttWordId).Value;

            // TODO: определить ElementType

            // ChildTreeInit
            // вершиной дерева всегда будет ID слова
            ChildWordsIds.AddChild(Id);

            // Order
            var orderNodeName = XName.Get(Consts.NodeWordOrder);
            Debug.Assert(elementXML.Element(orderNodeName) != null);
            Order = int.Parse(elementXML.Element(orderNodeName).Value);

            // Position - only in LWS
            var positionNodeName = XName.Get(Consts.NodeWordPosition);
            if (elementXML.Element(positionNodeName) != null)
                Position = int.Parse(elementXML.Element(Consts.NodeWordPosition).Value);
            else
                Position = -1;

            // Text
            var textNodeName = XName.Get(Consts.NodeWordText);
            if (elementXML.Element(textNodeName) != null)
                Text = elementXML.Element(textNodeName).Value;
            else
                Text = "";

            // Syntactic Role
            var syntacticRoleNodeName = XName.Get(Consts.NodeSyntacticRole);
            if (elementXML.Element(syntacticRoleNodeName) != null)
                SyntacticRole = SyntacticRole.ReadFromString(elementXML.Element(syntacticRoleNodeName).Value);
            else
                SyntacticRole = SyntacticRole.Undefined;

            // Surface slot
            if (elementXML.Element(Consts.NodeSurfaceSlot) != null)
                SurfaceSlot = SurfaceSlot.ReadFromString(elementXML.Element(Consts.NodeSurfaceSlot).Value);
            else
                SurfaceSlot = SurfaceSlot.Undefined;

            // grammar info
            if (elementXML.Element(Consts.NodeGrammarInfo) != null)
                GrammarInfo = new GrammarInfo(elementXML.Element(Consts.NodeGrammarInfo));
            else
            {
                GrammarInfo = new GrammarInfo();
                GrammarInfo.Case = GrammarInfoCase.Undefined;
                GrammarInfo.PartOfSpeech = GrammarInfoPartOfSpeech.Undefined;
            }

            // is restored
            if (elementXML.Element(Consts.NodeIsRestored) != null)
            {
                if (elementXML.Element(Consts.NodeIsRestored).Value == Consts.ValueTrue)
                    IsRestored = true;
                else IsRestored = false;
            }
            else
                IsRestored = false;

            //is word
            IsWord = elementXML.Attribute("type").Value == "Word";

            // syntactic parent id
            if (elementXML.Element(Consts.NodeSyntacticParent) != null)
                SyntacticParentWordId = elementXML.Element(Consts.NodeSyntacticParent).Attribute(Consts.AttWithWordId).Value;
            else
                SyntacticParentWordId = "-1";

            // controller nodes
            if (elementXML.Element(Consts.NodeHasController) != null)
            {
                foreach (var controllerItemXML in elementXML.Elements(Consts.NodeHasController))
                    ControllerNodes.Add(new Controller(controllerItemXML));
            }

            // conjucted with
            if (elementXML.Element(Consts.NodeConjuctedWith) != null)
                ConjuctedWithId = elementXML.Element(Consts.NodeConjuctedWith).Attribute(Consts.AttWithWordId).Value;
            else
                ConjuctedWithId = "-1";

            // semantic info
            SemanticInfo = new SemanticInfo(elementXML.Element(Consts.NodeSemanticInfo));
        }
Example #15
0
        private static SemanticInfo ExtractSemanticInfo(Type modelType)
        {
            SemanticInfo semanticInfo = new SemanticInfo();

            // Get model type name
            string modelTypeName = modelType.BareTypeName();

            // Built-in semantic type mapping
            semanticInfo.MappedSemanticTypes.Add(SemanticMapping.GetQualifiedTypeName(modelTypeName));

            // Extract semantic info from SemanticEntity attributes on the Model Type.
            foreach (SemanticEntityAttribute attribute in modelType.GetCustomAttributes <SemanticEntityAttribute>(inherit: true))
            {
                semanticInfo.MappedSemanticTypes.Add(SemanticMapping.GetQualifiedTypeName(attribute.EntityName, attribute.Vocab));

                string prefix = attribute.Prefix ?? string.Empty;
                if (attribute.Public && !String.IsNullOrEmpty(attribute.Prefix))
                {
                    string registeredVocab;
                    if (semanticInfo.PrefixMappings.TryGetValue(prefix, out registeredVocab))
                    {
                        // Prefix mapping already exists; must match.
                        if (attribute.Vocab != registeredVocab)
                        {
                            throw new DxaException(
                                      String.Format("Attempt to use semantic prefix '{0}' for vocabulary '{1}', but is is already used for vocabulary '{2}",
                                                    prefix, attribute.Vocab, registeredVocab)
                                      );
                        }
                    }
                    else
                    {
                        semanticInfo.PrefixMappings.Add(prefix, attribute.Vocab);
                    }
                    semanticInfo.PublicSemanticTypes.Add(String.Format("{0}:{1}", prefix, attribute.EntityName));
                }

                // There may be multiple Semantic Entity attributes for the same prefix. The first one will be used.
                if (semanticInfo.PrefixToSemanticTypeMap.ContainsKey(prefix))
                {
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug($"Type '{modelType.FullName}' has multiple SemanticEntity attributes for prefix '{prefix}'. Ignoring '{attribute.EntityName}'.");
                    }
                }
                else
                {
                    semanticInfo.PrefixToSemanticTypeMap.Add(prefix, new SemanticType(attribute.EntityName, attribute.Vocab));
                }
            }

            if (!semanticInfo.PrefixToSemanticTypeMap.ContainsKey(string.Empty))
            {
                // If there is no SemanticEntity attribute without prefix, we add an implicit one:
                semanticInfo.PrefixToSemanticTypeMap.Add(string.Empty, new SemanticType(modelTypeName, SemanticMapping.DefaultVocabulary));
            }

            string defaultPrefix;
            bool   mapAllProperties;
            SemanticDefaultsAttribute semanticDefaultsAttr = modelType.GetCustomAttribute <SemanticDefaultsAttribute>();

            if (semanticDefaultsAttr == null)
            {
                defaultPrefix    = string.Empty;
                mapAllProperties = true;
            }
            else
            {
                defaultPrefix    = semanticDefaultsAttr.Prefix;
                mapAllProperties = semanticDefaultsAttr.MapAllProperties;
            }

            foreach (PropertyInfo propertyInfo in modelType.GetProperties())
            {
                // Extract semantic info from SemanticEntity attributes on the Model Type's properties
                bool useImplicitMapping = mapAllProperties;

                List <SemanticPropertyAttribute> attributes = propertyInfo.GetCustomAttributes <SemanticPropertyAttribute>(inherit: true).ToList();

                // check if we should be ignoring this mapping completely
                if (attributes.Where(x => x.IgnoreMapping).Select(x => x).FirstOrDefault() != null)
                {
                    continue;
                }

                List <SemanticProperty> semanticProperties = new List <SemanticProperty>();
                foreach (SemanticPropertyAttribute attribute in attributes)
                {
                    if (string.IsNullOrEmpty(attribute.PropertyName))
                    {
                        continue;
                    }

                    // check for known property names
                    switch (attribute.PropertyName)
                    {
                    // To do : we need to make this more generic to collect all fields of a given type (e.g. [SemtanticProperty("_all", typeof(Keyword)])
                    case SemanticProperty.AllFields:
                        if (!typeof(IDictionary <string, string>).IsAssignableFrom(propertyInfo.PropertyType) &&
                            !typeof(IDictionary <string, KeywordModel>).IsAssignableFrom(propertyInfo.PropertyType))
                        {
                            throw new DxaException(
                                      $"Invalid semantics for property {modelType.Name}.{propertyInfo.Name}. Properties with [SemanticProperty(\"_all\")] annotation must be of type Dictionary<string, string> or Dictionary<string, KeywordModel>."
                                      );
                        }
                        break;

                    case SemanticProperty.Self:
                        Type elementType = GetElementType(propertyInfo.PropertyType);
                        if (!typeof(MediaItem).IsAssignableFrom(elementType) && !typeof(Link).IsAssignableFrom(elementType) && (elementType != typeof(string)) && (elementType != typeof(RichText)))
                        {
                            throw new DxaException(
                                      $"Invalid semantics for property {modelType.Name}.{propertyInfo.Name}. Properties with [SemanticProperty(\"_self\")] annotation must be of type MediaItem, Link, String or RichText.");
                        }
                        break;
                    }

                    string prefix = attribute.Prefix;
                    string name   = attribute.PropertyName;
                    if (prefix != null)
                    {
                        if (semanticInfo.PrefixMappings.ContainsKey(prefix))
                        {
                            IList <string> semanticPropertyNames;
                            if (!semanticInfo.SemanticProperties.TryGetValue(propertyInfo.Name, out semanticPropertyNames))
                            {
                                semanticPropertyNames = new List <string>();
                                semanticInfo.SemanticProperties.Add(propertyInfo.Name, semanticPropertyNames);
                            }
                            semanticPropertyNames.Add(attribute.PropertyName);
                        }
                    }
                    else
                    {
                        // Skip property names without prefix.
                        prefix             = defaultPrefix;
                        useImplicitMapping = false;
                    }

                    SemanticType semanticType;
                    if (!semanticInfo.PrefixToSemanticTypeMap.TryGetValue(prefix, out semanticType))
                    {
                        throw new DxaException($"Use of undeclared prefix '{prefix}' in property '{propertyInfo.Name}' in type '{modelType.FullName}'.");
                    }
                    semanticProperties.Add(new SemanticProperty(prefix, name, semanticType));
                }

                if (useImplicitMapping)
                {
                    SemanticType semanticType;
                    if (!semanticInfo.PrefixToSemanticTypeMap.TryGetValue(defaultPrefix, out semanticType))
                    {
                        throw new DxaException($"Use of undeclared prefix '{defaultPrefix}' in property '{propertyInfo.Name}' in type '{modelType.FullName}'.");
                    }
                    SemanticProperty implicitSemanticProperty = new SemanticProperty(
                        String.Empty, GetDefaultSemanticPropertyName(propertyInfo),
                        semanticType
                        );

                    semanticProperties.Add(implicitSemanticProperty);
                }

                if (semanticProperties.Count > 0)
                {
                    if (semanticInfo.PropertySemantics.ContainsKey(propertyInfo.Name))
                    {
                        // Properties with same name can exist is a property is reintroduced with a different signature in a subclass.
                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug("Property with name '{0}' is declared multiple times in type {1}.", propertyInfo.Name, modelType.FullName);
                        }
                    }
                    else
                    {
                        semanticInfo.PropertySemantics.Add(propertyInfo.Name, semanticProperties);
                    }
                }
            }

            return(semanticInfo);
        }
Example #16
0
        // <term> ::= <factor> <term2>
        protected bool NTF_Term(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, Lexer.Token.TokenType.Identifier, Lexer.Token.TokenType.OpenBracket, Lexer.Token.TokenType.Not,
                Lexer.Token.TokenType.Number,
                Lexer.Token.TokenType.Multiplicative, Lexer.Token.TokenType.Comma, Lexer.Token.TokenType.CloseBracket,
                Lexer.Token.TokenType.Comparison, Lexer.Token.TokenType.Additive, Lexer.Token.TokenType.Semicolon);

            error |= !NTF_Factor(p, si);
            error |= !NTF_Term2(p, si);

            if (!error && p == 1)
                Log(LogType.Parse, "<term> ::= <factor> <term2>");

            return !error;
        }
Example #17
0
        public override void CheckSemantic(SymbolTable symbolTable, List <CompileError> errors)
        {
            SemanticInfo callableInfo;

            ///la función o procedimiento tiene que estar declarada(o)
            if (!symbolTable.GetDefinedCallableDeep(CallableId, out callableInfo))
            {
                errors.Add(new CompileError
                {
                    Line         = Callable.Line,
                    Column       = Callable.CharPositionInLine,
                    ErrorMessage = string.Format("The name '{0}' could not be found in current context", CallableId),
                    Kind         = ErrorKind.Semantic
                });

                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
                return;
            }

            ///la cantidad de argumentos tiene que coincidir con los de su declaración
            if (callableInfo.Args.Count != ArgsCount)
            {
                errors.Add(new CompileError
                {
                    Line         = this.Line,
                    Column       = this.CharPositionInLine,
                    ErrorMessage = string.Format("No overload for {0} '{1}' takes {2} arguments", (callableInfo.ElementKind == SymbolKind.Function) ? "function" : "procedure", CallableId, ArgsCount),
                    Kind         = ErrorKind.Semantic
                });

                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
                return;
            }


            ExpressionNode currentArg;

            ///los tipos de los argumentos tienen que coincidir con los de su definición
            for (int i = 0; i < ArgsCount; i++)
            {
                ///obtenemos el i-ésimo argumento
                currentArg = ArgAt(i + 1);

                ///check semantics a currentArg
                currentArg.CheckSemantic(symbolTable, errors);

                ///si currentArg no evaluó de error
                if (!Object.Equals(currentArg.NodeInfo, SemanticInfo.SemanticError))
                {
                    ///si no coinciden los tipos
                    if (!callableInfo.Args[i].Type.IsCompatibleWith(currentArg.NodeInfo.Type))
                    {
                        errors.Add(new CompileError
                        {
                            Line         = currentArg.Line,
                            Column       = currentArg.CharPositionInLine,
                            ErrorMessage = string.Format("Argument {0}: cannot convert from '{1}' to '{2}'", i + 1, currentArg.NodeInfo.Type.Name, callableInfo.Args[i].Type.Name),
                            Kind         = ErrorKind.Semantic
                        });

                        ///el nodo evalúa de error
                        NodeInfo = SemanticInfo.SemanticError;
                    }
                }
                else
                {
                    ///hubo una argumento que evaluó de error

                    ///el nodo evalúa de error
                    NodeInfo = SemanticInfo.SemanticError;
                }
            }

            ///seteamos la información del NodeInfo
            if (!Object.Equals(NodeInfo, SemanticInfo.SemanticError))
            {
                NodeInfo = new SemanticInfo
                {
                    Name        = SemanticInfo.NoName,
                    ElementKind = SymbolKind.NoSymbol,
                    BuiltInType = callableInfo.BuiltInType,
                    Type        = callableInfo.Type,

                    ElementsType = callableInfo.ElementsType,
                    Fields       = callableInfo.Fields
                };
            }
        }
        public override void CheckSemantic(SymbolTable symbolTable, List <CompileError> errors)
        {
            SemanticInfo fieldInfo;

            for (int i = 0; i < FieldsCount; i++)
            {
                ///los tipos de los campos tienen que haber sido declarados
                if (!symbolTable.GetDefinedTypeDeep(Fields[i].Value, out fieldInfo))
                {
                    errors.Add(new CompileError
                    {
                        Line         = GetChild(2 * i + 2).Line,
                        Column       = GetChild(2 * i + 2).CharPositionInLine,
                        ErrorMessage = string.Format("Type '{0}' could not be found in current context", Fields[i].Value),
                        Kind         = ErrorKind.Semantic
                    });

                    ///el nodo evalúa de error
                    NodeInfo = SemanticInfo.SemanticError;
                }
                else
                {
                    realFields.Add(fieldInfo);
                }

                for (int j = 0; j < i; j++)
                {
                    ///chequeamos que no existan 2 campos con el mismo nombre
                    if (Fields[i].Key.Equals(Fields[j].Key))
                    {
                        errors.Add(new CompileError
                        {
                            Line         = GetChild(2 * i + 1).Line,
                            Column       = GetChild(2 * i + 1).CharPositionInLine,
                            ErrorMessage = string.Format("The field name '{0}' is a duplicate", Fields[i].Key),
                            Kind         = ErrorKind.Semantic
                        });

                        ///el nodo evalúa de error
                        NodeInfo = SemanticInfo.SemanticError;
                    }
                }
            }

            /////si no ha evaluado de error le seteamos los valores
            //if (!Object.Equals(NodeInfo, SemanticInfo.SemanticError))
            //{
            //    NodeInfo.Type = SemanticInfo.Void;
            //    NodeInfo.BuiltInType = BuiltInType.Void;
            //}

            ///si evaluó de error
            if (Object.Equals(NodeInfo, SemanticInfo.SemanticError))
            {
                ///no declaramos el record porque uno de sus campos no existe
                return;
            }

            ///seteamos la información del NodeInfo
            NodeInfo.Type        = SemanticInfo.Void;
            NodeInfo.BuiltInType = BuiltInType.Void;

            List <KeyValuePair <string, SemanticInfo> > fields = new List <KeyValuePair <string, SemanticInfo> >();

            ///guardamos los fields del record
            for (int i = 0; i < FieldsCount; i++)
            {
                fields.Add(new KeyValuePair <string, SemanticInfo>(Fields[i].Key, realFields[i]));
            }

            SemanticInfo recordAlias;

            symbolTable.GetDefinedTypeDeep(RecordId, out recordAlias);
            recordAlias.BuiltInType = BuiltInType.Record;
            recordAlias.Fields      = fields;
            recordAlias.IsPending   = false;
            recordAlias.Type        = recordAlias;

            recordParche = recordAlias;
        }
Example #19
0
        public override void CheckSemantic(SymbolTable symbolTable, List <CompileError> errors)
        {
            ///check semantics al VarDeclarationNode
            base.CheckSemantic(symbolTable, errors);

            ///check semantics al InitExpression
            InitExpression.CheckSemantic(symbolTable, errors);

            ///si InitExpression evalúa de error este también
            if (Object.Equals(InitExpression.NodeInfo, SemanticInfo.SemanticError))
            {
                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
                return;
            }

            SemanticInfo typeInfo;

            ///el tipo de la variable tiene que estar definido
            if (!symbolTable.GetDefinedTypeDeep(VarTypeId, out typeInfo))
            {
                errors.Add(new CompileError
                {
                    Line         = VarType.Line,
                    Column       = VarType.CharPositionInLine,
                    ErrorMessage = string.Format("Type '{0}' could not be found in current context", VarTypeId),
                    Kind         = ErrorKind.Semantic
                });

                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
            }

            ///si existe el tipo de la variable
            if (!Object.Equals(typeInfo, SemanticInfo.SemanticError))
            {
                ///el tipo de InitExpression y VarTypeId tienen que ser compatibles
                if (!InitExpression.NodeInfo.Type.IsCompatibleWith(typeInfo.Type))
                {
                    errors.Add(new CompileError
                    {
                        Line         = VarType.Line,
                        Column       = VarType.CharPositionInLine,
                        ErrorMessage = string.Format("Cannot implicitly convert type '{0}' to '{1}'", InitExpression.NodeInfo.Type.Name, VarTypeId),
                        Kind         = ErrorKind.Semantic
                    });

                    ///el nodo evalúa de error
                    NodeInfo = SemanticInfo.SemanticError;
                }
            }

            ///si no hubo error seteamos los campos necesarios
            if (!Object.Equals(NodeInfo, SemanticInfo.SemanticError))
            {
                NodeInfo.Type        = SemanticInfo.Void;
                NodeInfo.BuiltInType = BuiltInType.Void;
            }

            SemanticInfo variable = new SemanticInfo
            {
                Name        = VariableName,
                ElementKind = SymbolKind.Variable,
                BuiltInType = typeInfo.BuiltInType,
                Type        = typeInfo.Type,

                ElementsType = typeInfo.ElementsType,
                Fields       = typeInfo.Fields
            };

            ///guardamos el ILType en el NodeInfo
            NodeInfo.ILType = InitExpression.NodeInfo.ILType;

            ///agregamos la variable a la tabla de símbolos
            symbolTable.InsertSymbol(variable);
        }
Example #20
0
        // <array> ::= [ <int> ] | e
        protected bool NTF_Array(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, Lexer.Token.TokenType.OpenSquareBracket,
                Lexer.Token.TokenType.Comma, Lexer.Token.TokenType.CloseBracket, Lexer.Token.TokenType.Semicolon);

            if (lookahead.Type == Lexer.Token.TokenType.OpenSquareBracket)
            {
                SemanticInfo inti = new SemanticInfo();

                error |= !Match(p, Lexer.Token.TokenType.OpenSquareBracket);
                error |= !NTF_Int(p, inti);
                error |= !Match(p, Lexer.Token.TokenType.CloseSquareBracket);

                si.ArrayIndices.Add(inti.Name);

                if (!error && p == 1)
                    Log(LogType.Parse, "<array> ::= [ <int> ]");
            }
            // follow=,+)+;
            else if (lookahead.Type == Lexer.Token.TokenType.Comma || lookahead.Type == Lexer.Token.TokenType.CloseBracket
                || lookahead.Type == Lexer.Token.TokenType.Semicolon)
            {
                if (p == 1)
                    Log(LogType.Parse, "<array> ::= e");
            }
            else
                error = true;

            return !error;
        }
Example #21
0
        // <arraystar> ::= e | <array> <arraystar>
        protected bool NTF_ArrayStar(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, Lexer.Token.TokenType.OpenSquareBracket,
                Lexer.Token.TokenType.Semicolon, Lexer.Token.TokenType.Comma, Lexer.Token.TokenType.CloseBracket);

            if (lookahead.Type == Lexer.Token.TokenType.OpenSquareBracket)
            {
                error |= !NTF_Array(p, si);
                error |= !NTF_ArrayStar(p, si);

                if (!error && p == 1)
                    Log(LogType.Parse, "<arraystar> ::= <array> <arraystar>");
            }
            // follow=;+,+)
            else
                if (lookahead.Type == Lexer.Token.TokenType.Semicolon || lookahead.Type == Lexer.Token.TokenType.Comma
                    || lookahead.Type == Lexer.Token.TokenType.CloseBracket)
                {
                    if (p == 1)
                        Log(LogType.Parse, "<arraystar> ::= e");
                }
                else
                    error = true;

            return !error;
        }
Example #22
0
        // <arithexpr> ::= <term> <arithexpr2> | <sign> <term> <arithexpr2>
        protected bool NTF_ArithExpr(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, "+", "-", Lexer.Token.TokenType.Identifier, Lexer.Token.TokenType.Number,
                Lexer.Token.TokenType.OpenBracket, Lexer.Token.TokenType.Not,
                Lexer.Token.TokenType.Comparison, Lexer.Token.TokenType.Additive, Lexer.Token.TokenType.CloseSquareBracket,
                Lexer.Token.TokenType.Comma, Lexer.Token.TokenType.CloseBracket, Lexer.Token.TokenType.Semicolon);

            // first(<term>)=first(<variable>)+num+(+!
            if (lookahead.Type == Lexer.Token.TokenType.Identifier || lookahead.Type == Lexer.Token.TokenType.Number
                || lookahead.Type == Lexer.Token.TokenType.OpenBracket || lookahead.Type == Lexer.Token.TokenType.Not)
            {
                error |= !NTF_Term(p, si);
                error |= !NTF_ArithExpr2(p, si);

                if (!error && p == 1)
                    Log(LogType.Parse, "<arithexpr> ::= <term> <arithexpr2>");
            }
            else if (lookahead.Value == "+" || lookahead.Value == "-")
            {
                SemanticInfo si2 = new SemanticInfo();
                error |= !NTF_Sign(p, si2);
                error |= !NTF_Term(p, si);
                si.Code.Append(si2.Code);
                error |= !NTF_ArithExpr2(p, si);

                if (!error && p == 1)
                    Log(LogType.Parse, "<arithexpr> ::= <sign> <term> <arithexpr2>");
            }
            else
                error = true;

            return !error;
        }
Example #23
0
        // <arithexpr2> ::= e | addop <term><arithexpr2>
        protected bool NTF_ArithExpr2(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, Lexer.Token.TokenType.Additive,
                Lexer.Token.TokenType.Semicolon, Lexer.Token.TokenType.CloseBracket, Lexer.Token.TokenType.Comparison,
                Lexer.Token.TokenType.CloseSquareBracket, Lexer.Token.TokenType.Comma);

            // first(<arithexpr2>)=addop
            if (lookahead.Type == Lexer.Token.TokenType.Additive)
            {
                string op = lookahead.Value;
                if (op == "+") op = "add";
                else if (op == "-") op = "sub";
                else if (op == "||") op = "or";
                error |= !Match(p, Lexer.Token.TokenType.Additive);
                SemanticInfo si2 = new SemanticInfo();
                error |= !NTF_Term(p, si2);
                if (p == 2)
                {
                    if (si.Type == "int" && si2.Type == "int")
                    {
                        // TODO: handle logical or (and and)
                        // paste si2 then add the 2 together freeing up the temp vars if needed
                        si.Code.Append(si2.Code);
                        si.Code.Append("addi r3,r14," + si.Offset + "\nlw r1,stack(r3)\n" +
                            "addi r3,r14," + si2.Offset + "\nlw r2,stack(r3)\n" + op + " r1,r1,r2\n");

                        CompilerStack.Peek().SafeFreeTemp(si.Offset);
                        CompilerStack.Peek().SafeFreeTemp(si2.Offset);

                        int tmp = CompilerStack.Peek().RequestTemp() + CompilerStack.Peek().GetTotalRealOffset();
                        si.Code.Append("addi r2,r14," + tmp + "\nsw stack(r2),r1\n");
                        si.Offset = tmp;
                    }
                }
                error |= !NTF_ArithExpr2(p, si);

                if (!error && p == 1)
                    Log(LogType.Parse, "<arithexpr2> ::= addop <term> <arithexpr2>");
            }
            // follow(<arithexpr2>)=follow(<arithexpr>)=follow(<expr>)+relop+addop+]+,+follow(<aparams>)
            //                     =;+)+relop+addop+]+,
            else if (lookahead.Type == Lexer.Token.TokenType.Semicolon || lookahead.Type == Lexer.Token.TokenType.CloseBracket
                || lookahead.Type == Lexer.Token.TokenType.Additive || lookahead.Type == Lexer.Token.TokenType.Comparison
                || lookahead.Type == Lexer.Token.TokenType.CloseSquareBracket || lookahead.Type == Lexer.Token.TokenType.Comma)
            {
                if (p == 1)
                    Log(LogType.Parse, "<arithexpr2> ::= e");
            }
            else
                error = true;

            return !error;
        }
Example #24
0
        // <aparamstailstar> ::= e | <aparamstail> <aparamstailstar>
        protected bool NTF_AParamsTailStar(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, Lexer.Token.TokenType.Comma, Lexer.Token.TokenType.CloseBracket);

            if (lookahead.Type == Lexer.Token.TokenType.Comma)
            {
                // TODO: handle function params
                error |= !NTF_AParamsTail(p, si);
                error |= !NTF_AParamsTailStar(p, si);

                if (!error && p == 1)
                    Log(LogType.Parse, "<aparamstailstar> ::= <apramstail> <aparamstailstar>");
            }
            // follow=)
            else if (lookahead.Type == Lexer.Token.TokenType.CloseBracket)
            {
                if (p == 1)
                    Log(LogType.Parse, "<aparamstailstar> ::= e");
            }
            else
                error = true;

            return !error;
        }
Example #25
0
        // <apramstail> ::= , <arithexpr> | e
        protected bool NTF_AParamsTail(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, Lexer.Token.TokenType.Comma, Lexer.Token.TokenType.CloseBracket);

            if (lookahead.Type == Lexer.Token.TokenType.Comma)
            {
                SemanticInfo si2 = new SemanticInfo();
                error |= !Match(p, Lexer.Token.TokenType.Comma);
                error |= !NTF_ArithExpr(p, si2);
                if (p == 2)
                    si.Parameters.Add(new SemanticInfo.ParameterInfo
                    {
                        Code = si2.Code,
                        OldFrameOffset = si2.Offset,
                        Type = si2.Type,
                    });

                if (!error && p == 1)
                    Log(LogType.Parse, "<aparamstail> ::= , <arithexpr>");
            }
            else if (lookahead.Type == Lexer.Token.TokenType.CloseBracket)
            {
                if (p == 1)
                    Log(LogType.Parse, "<araparmstail> ::= e");
            }
            else
                error = true;

            return !error;
        }
Example #26
0
        // <aparams> ::= <arithexpr> <aparamstailstar> | e
        protected bool NTF_AParams(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, "+", "-", Lexer.Token.TokenType.Identifier, Lexer.Token.TokenType.Number,
                Lexer.Token.TokenType.OpenBracket, Lexer.Token.TokenType.Not, Lexer.Token.TokenType.CloseBracket);

            // first(<arithexpr>)=++-+first(<term>)=++-+id+num+(+!
            if (lookahead.Value == "+" || lookahead.Value == "-" || lookahead.Type == Lexer.Token.TokenType.Identifier
                || lookahead.Type == Lexer.Token.TokenType.Number || lookahead.Type == Lexer.Token.TokenType.OpenBracket
                || lookahead.Type == Lexer.Token.TokenType.Not)
            {
                SemanticInfo si2 = new SemanticInfo();
                error |= !NTF_ArithExpr(p, si2);
                if (p == 2)
                    si.Parameters.Add(new SemanticInfo.ParameterInfo
                    {
                        Code = si2.Code,
                        OldFrameOffset = si2.Offset,
                        Type = si2.Type,
                    });
                error |= !NTF_AParamsTailStar(p, si2);

                if (!error && p == 1)
                    Log(LogType.Parse, "<aparams> ::= <arithexpr> <aparamstail>");
            }
            // follow = )
            else if (lookahead.Type == Lexer.Token.TokenType.CloseBracket)
            {
                if (p == 1)
                    Log(LogType.Parse, "<aparams> ::= e");
            }
            else
                error = true;

            return !error;
        }
Example #27
0
        // <progbody> ::= program <funcbody>;<functionstar>
        // MODIFIED
        // <progbody> ::= program <funcbody>;<definitionstar>
        protected bool NTF_ProgBody(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, "program", Lexer.Token.TokenType.EndOfFile);

            if (p == 1)
            {
                SymbolTable.Information info;
                if ((info = CurrentScope.Find("$program", false)) != null)
                {
                    SemanticErrorSymbolAlreadyDefined("$program");
                    error = true;
                    if (info.Properties.ContainsKey("function_symtable"))
                        if (info.Properties["function_symtable"] != null)
                            CurrentScope = info.Properties["function_symtable"] as SymbolTable;
                        else
                            info.Properties["function_symtable"] = CurrentScope = CurrentScope.CreateChild("$program");
                    else
                    {
                        info.Properties.Add("function_symtable", CurrentScope.CreateChild("$program"));
                        CurrentScope = info.Properties["function_symtable"] as SymbolTable;
                    }
                }
                else
                {
                    info = CurrentScope.Add("$program");
                    info.Kind = SymbolTable.Information.EKind.Function;
                    info.Properties.Add("function_symtable", CurrentScope.CreateChild("$program"));
                    info.Properties.Add("function_parameters", new List<SemanticInfo.ParameterInfo>());
                    info.Properties.Add("function_type", "<no type>");
                    CurrentScope = info.Properties["function_symtable"] as SymbolTable;
                }
            }
            else
                CurrentScope = CurrentScope.Find("$program", false).Properties["function_symtable"] as SymbolTable;

            if (p == 2)
                si.Code.Append("entry\n\nalign\naddi r14,r0,0\n");

            error |= !Match(p, "program");
            error |= !NTF_FuncBody(p, si);
            error |= !Match(p, Lexer.Token.TokenType.Semicolon);

            si.Code.Append("hlt\n");

            CurrentScope = CurrentScope.Parent;

            error |= !NTF_DefinitionStar(p, si);

            if (!error && p == 1)
                Log(LogType.Parse, "<progbody> ::= program <funcbody> ; <definitionstar>");

            return !error;
        }
Example #28
0
        // <classdecl> ::= class id { <typedeclstar> <functionstar> } ;
        // MODIFIED
        // <classdecl> ::= class id { <definitionstar> } ;
        protected bool NTF_ClassDecl(int p, SemanticInfo si)
        {
            /*
                        if (Match("class") && Match(Lexer.Token.TokenType.Identifier) && Match(Lexer.Token.TokenType.OpenBrace)
                            && NTF_TypeDeclStar() && NTF_FunctionStar() && Match(Lexer.Token.TokenType.CloseBrace)
                            && Match(Lexer.Token.TokenType.Semicolon))
                        {
                            Log("<classdecl> ::= class id {<typedeclstar><functionstar>};");
                            return true;
                        }
                        else
                            return false;
            */
            bool error = SkipErrors(p, "class", "program");

            error |= !Match(p, "class");

            if (p == 1)
            {
                SymbolTable child;
                SymbolTable.Information info;
                if ((info = CurrentScope.Find(lookahead.Value, false)) != null)
                {
                    SemanticErrorSymbolAlreadyDefined(lookahead.Value);
                    error = true;
                    if (info.Properties.ContainsKey("class_symtable"))
                        if (info.Properties["class_symtable"] != null)
                            child = info.Properties["class_symtable"] as SymbolTable;
                        else
                            info.Properties["class_symtable"] = child = CurrentScope.CreateChild(lookahead.Value);
                    else
                    {
                        info.Properties.Add("class_symtable", CurrentScope.CreateChild(lookahead.Value));
                        child = info.Properties["class_symtable"] as SymbolTable;
                    }
                }
                else
                {
                    info = CurrentScope.Add(lookahead.Value);
                    child = CurrentScope.CreateChild(lookahead.Value);

                    info.Kind = SymbolTable.Information.EKind.Class;
                    info.Properties.Add("class_symtable", child);
                }

                CurrentScope = child;
            }
            else
            {
                CurrentScope = CurrentScope.Find(lookahead.Value, false).Properties["class_symtable"] as SymbolTable;
            }

            error |= !Match(p, Lexer.Token.TokenType.Identifier);
            error |= !Match(p, Lexer.Token.TokenType.OpenBrace);
            error |= !NTF_DefinitionStar(p, si);
            error |= !Match(p, Lexer.Token.TokenType.CloseBrace);
            error |= !Match(p, Lexer.Token.TokenType.Semicolon);

            CurrentScope = CurrentScope.Parent;

            if (!error && p == 1)
                Log(LogType.Parse, "<classdecl> := class id { <definitionstar> } ;");

            return !error;
        }
Example #29
0
        private static SemanticInfo ExtractSemanticInfo(Type modelType)
        {
            SemanticInfo semanticInfo = new SemanticInfo();

            // Built-in semantic type mapping
            string bareTypeName = modelType.Name.Split('`')[0]; // Type name without generic type parameters (if any)

            semanticInfo.MappedSemanticTypes.Add(SemanticMapping.GetQualifiedTypeName(bareTypeName));

            // Extract semantic info from SemanticEntity attributes on the Model Type.
            foreach (SemanticEntityAttribute attribute in modelType.GetCustomAttributes(true).Where(a => a is SemanticEntityAttribute))
            {
                semanticInfo.MappedSemanticTypes.Add(SemanticMapping.GetQualifiedTypeName(attribute.EntityName, attribute.Vocab));

                if (!attribute.Public || string.IsNullOrEmpty(attribute.Prefix))
                {
                    continue;
                }

                string prefix = attribute.Prefix;
                string registeredVocab;
                if (semanticInfo.PrefixMappings.TryGetValue(prefix, out registeredVocab))
                {
                    // Prefix mapping already exists; must match.
                    if (attribute.Vocab != registeredVocab)
                    {
                        throw new DxaException(
                                  string.Format("Attempt to use semantic prefix '{0}' for vocabulary '{1}', but is is already used for vocabulary '{2}",
                                                prefix, attribute.Vocab, registeredVocab)
                                  );
                    }
                }
                else
                {
                    semanticInfo.PrefixMappings.Add(prefix, attribute.Vocab);
                }

                semanticInfo.PublicSemanticTypes.Add(String.Format("{0}:{1}", prefix, attribute.EntityName));
            }

            // Extract semantic info from SemanticEntity attributes on the Model Type's properties
            foreach (MemberInfo memberInfo in modelType.GetMembers(BindingFlags.Public | BindingFlags.Instance))
            {
                foreach (SemanticPropertyAttribute attribute in memberInfo.GetCustomAttributes(true).Where(a => a is SemanticPropertyAttribute))
                {
                    if (string.IsNullOrEmpty(attribute.PropertyName))
                    {
                        // Skip properties without name.
                        continue;
                    }
                    string[] semanticPropertyNameParts = attribute.PropertyName.Split(':');
                    if (semanticPropertyNameParts.Length < 2)
                    {
                        // Skip property names without prefix.
                        continue;
                    }
                    string prefix = semanticPropertyNameParts[0];
                    if (!semanticInfo.PrefixMappings.ContainsKey(prefix))
                    {
                        // Skip property names with prefix which is not declared as public prefix on the type.
                        continue;
                    }

                    IList <string> semanticPropertyNames;
                    if (!semanticInfo.SemanticProperties.TryGetValue(memberInfo.Name, out semanticPropertyNames))
                    {
                        semanticPropertyNames = new List <string>();
                        semanticInfo.SemanticProperties.Add(memberInfo.Name, semanticPropertyNames);
                    }
                    semanticPropertyNames.Add(attribute.PropertyName);
                }
            }

            return(semanticInfo);
        }
Example #30
0
        // <classdeclstar> ::= e | <classdecl><classdeclstar>
        protected bool NTF_ClassDeclStar(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, "class", "program");

            if (lookahead.Value == "class")                                    // first(<classdecl>)
            {
                error |= !NTF_ClassDecl(p, si);
                error |= !NTF_ClassDeclStar(p, si);

                if (!error && p == 1)
                    Log(LogType.Parse, "<classdeclstar> ::= <classdecl><classdeclstar>");
            }
            else
                if (lookahead.Value == "program")                              // follow(<classdecl>)
                {
                    if (p == 1)
                        Log(LogType.Parse, "<classdeclstar> ::= e");
                }
                else
                    error = true;

            return !error;
        }
Example #31
0
        // <variable> ::= <idnest> <indicestar>
        protected bool NTF_Variable(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, Lexer.Token.TokenType.Identifier,
                Lexer.Token.TokenType.Assignement, Lexer.Token.TokenType.Multiplicative, Lexer.Token.TokenType.Additive,
                Lexer.Token.TokenType.Comparison, Lexer.Token.TokenType.Comma, Lexer.Token.TokenType.CloseBracket,
                Lexer.Token.TokenType.Semicolon);

            SemanticInfo si2 = new SemanticInfo();
            error |= !NTF_IdNest(p, si2);
            error |= !NTF_IndiceStar(p, si2);

            if (p == 2)
            {
                // find the type of this variable
                SymbolTable st = CurrentScope;
                SymbolTable.Information info;

                si.Offset = 0;

                foreach (SemanticInfo.ParameterInfo pi in si2.Parameters)
                {
                    info = st.Find(pi.Name, true);
                    if (info == null || info.Kind != SymbolTable.Information.EKind.Variable)
                    {
                        SemanticErrorVariableNotFound(pi.Name);
                        return false;
                    }

                    si.Offset += (int)info.Properties["variable_offset"];
                    info = Global.Find(info.Properties["variable_type"] as string, false);
                    if (info == null || info.Kind != SymbolTable.Information.EKind.Class)
                    {
                        SemanticErrorWrongType(pi.Name);
                        return false;
                    }

                    st = info.Properties["class_symtable"] as SymbolTable;
                }

                info = st.Find(si2.Name, si2.Parameters.Count == 0);
                if (info == null || info.Kind != SymbolTable.Information.EKind.Variable)
                {
                    SemanticErrorVariableNotFound(si.Name);
                    return false;
                }

                si.Type = (string)info.Properties["variable_type"];
                si.Offset += (int)info.Properties["variable_offset"];
            }

            if (!error && p == 1)
                Log(LogType.Parse, "<variable> ::= <idnest> <indicestar>");

            return !error;
        }
Example #32
0
        // <definition> ::= <type> id <definition2>
        protected bool NTF_Definition(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, "int", "float", Lexer.Token.TokenType.Identifier, Lexer.Token.TokenType.CloseBrace,
                Lexer.Token.TokenType.EndOfFile);

            error |= !NTF_Type(p, si);

            si.Name = lookahead.Value;
            error |= !Match(p, Lexer.Token.TokenType.Identifier);

            error |= !NTF_Definition2(p, si);

            if (!error && p == 1)
                Log(LogType.Parse, "<definition> ::= <type> id <definition2>");

            return !error;
        }
Example #33
0
        // <term2> ::= e | multop <factor> <term2>
        protected bool NTF_Term2(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, Lexer.Token.TokenType.Multiplicative,
                Lexer.Token.TokenType.Semicolon, Lexer.Token.TokenType.CloseBracket, Lexer.Token.TokenType.Additive,
                Lexer.Token.TokenType.Comparison, Lexer.Token.TokenType.CloseSquareBracket, Lexer.Token.TokenType.Comma);

            if (lookahead.Type == Lexer.Token.TokenType.Multiplicative)
            {
                string op = lookahead.Value;
                if (op == "*") op = "mul";
                else if (op == "/") op = "div";
                else if (op == "&&") op = "and";
                error |= !Match(p, Lexer.Token.TokenType.Multiplicative);

                SemanticInfo si2 = new SemanticInfo();
                error |= !NTF_Factor(p, si2);

                if (p == 2)
                {
                    // TODO: handle more types
                    if (si.Type == "int" && si2.Type == "int")
                    {
                        // TODO: handle logical or (and and)
                        // paste si2 then add the 2 together freeing up the temp vars if needed
                        si.Code.Append(si2.Code);
                        si.Code.Append("addi r3,r14," + si.Offset + "\nlw r1,stack(r3)\n" +
                            "addi r3,r14," + si2.Offset + "\nlw r2,stack(r3)\n" + op + " r1,r1,r2\n");

                        CompilerStack.Peek().SafeFreeTemp(si.Offset);
                        CompilerStack.Peek().SafeFreeTemp(si2.Offset);

                        int tmp = CompilerStack.Peek().RequestTemp() + CompilerStack.Peek().GetTotalRealOffset();
                        si.Code.Append("addi r2,r14," + tmp + "\nsw stack(r2),r1\n");
                        si.Offset = tmp;
                    }
                    else
                    {
                        if (si.Type != "int")
                            SemanticErrorWrongType(si.Name);
                        if (si2.Type != "int")
                            SemanticErrorWrongType(si2.Name);

                        error = true;
                    }
                }

                error |= !NTF_Term2(p, si);

                if (!error && p == 1)
                    Log(LogType.Parse, "<term2> ::= multop <factor> <term2>");
            }
            // follow(<term2>)=follow(<term>)=follow(<arithexpr>)=;+)+relop+addop+]+,
            else if (lookahead.Type == Lexer.Token.TokenType.Semicolon || lookahead.Type == Lexer.Token.TokenType.CloseBracket
                || lookahead.Type == Lexer.Token.TokenType.Additive || lookahead.Type == Lexer.Token.TokenType.Comparison
                || lookahead.Type == Lexer.Token.TokenType.CloseSquareBracket || lookahead.Type == Lexer.Token.TokenType.Comma)
            {
                if (p == 1)
                    Log(LogType.Parse, "<term2> ::= e");
            }
            else
                error = true;

            return !error;
        }
Example #34
0
        // <definition2> ::= ( <fparams> ) <funcbody> ;
        //                 | <arraystar> ;
        protected bool NTF_Definition2(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, Lexer.Token.TokenType.OpenBracket, Lexer.Token.TokenType.OpenSquareBracket,
                Lexer.Token.TokenType.Semicolon,
                Lexer.Token.TokenType.CloseBrace, Lexer.Token.TokenType.EndOfFile);

            if (lookahead.Type == Lexer.Token.TokenType.OpenBracket)
            {
                error |= !Match(p, Lexer.Token.TokenType.OpenBracket);
                SemanticInfo si2 = new SemanticInfo();
                error |= !NTF_FParams(p, si2);
                error |= !Match(p, Lexer.Token.TokenType.CloseBracket);

                if (p == 1)
                {
                    SymbolTable.Information info;
                    if ((info = CurrentScope.Find(si.Name, false)) != null)
                    {
                        SemanticErrorSymbolAlreadyDefined(si.Name);
                        error = true;

                        if (info.Properties.ContainsKey("function_symtable"))
                            if (info.Properties["function_symtable"] != null)
                                CurrentScope = info.Properties["function_symtable"] as SymbolTable;
                            else
                                info.Properties["function_symtable"] = CurrentScope = CurrentScope.CreateChild(si.Name);
                        else
                        {
                            info.Properties.Add(si.Name, CurrentScope.CreateChild(si.Name));
                            CurrentScope = info.Properties[si.Name] as SymbolTable;
                        }
                    }
                    else
                    {
                        info = CurrentScope.Add(si.Name);
                        info.Kind = SymbolTable.Information.EKind.Function;
                        info.Properties.Add("function_parameters", si2.Parameters);
                        info.Properties.Add("function_type", si.Type);
                        info.Properties.Add("function_symtable", CurrentScope.CreateChild(si.Name));
                        CurrentScope = info.Properties["function_symtable"] as SymbolTable;

                        // also add the parameters as member variables
                        foreach (SemanticInfo.ParameterInfo pi in si2.Parameters)
                        {
                            SymbolTable.Information inf = (info.Properties["function_symtable"] as SymbolTable)
                                .Add(pi.Name);
                            inf.Kind = SymbolTable.Information.EKind.Variable;
                            inf.Properties.Add("variable_type", pi.Type);
                            inf.Properties.Add("variable_arrayindices", pi.ArrayIndices.ToArray());
                            //inf.Properties.Add("variable_offset", CompilerStack.Peek().GetTotalRealOffset());
                        }
                    }
                }
                else
                {
                    si.Code.Append(si2.Code);
                    CurrentScope = CurrentScope.Find(si.Name, false).Properties["function_symtable"] as SymbolTable;
                }

                CompilerStack.Push(new StackFrame(this, true));

                // the function label
                if (p == 2)
                    si.Code.Append(GetFunctionLabelName(CurrentScope.Parent, si.Name) + " nop\n");
                error |= !NTF_FuncBody(p, si);
                error |= !Match(p, Lexer.Token.TokenType.Semicolon);
                if (p == 2)
                    si.Code.Append("% append default return\naddi r1,r0,0\njr r15\n");

                CompilerStack.Pop();

                CurrentScope = CurrentScope.Parent;

                if (!error && p == 1)
                    Log(LogType.Parse, "<definition2> ::= ( <fparams> ) <funcbody> ;");
            }
            else if (lookahead.Type == Lexer.Token.TokenType.OpenSquareBracket || lookahead.Type == Lexer.Token.TokenType.Semicolon)
            {
                error |= !NTF_ArrayStar(p, si);
                error |= !Match(p, Lexer.Token.TokenType.Semicolon);

                if (p == 1)
                {
                    SymbolTable.Information info;
                    if ((info = CurrentScope.Find(si.Name, false)) != null)
                    {
                        SemanticErrorSymbolAlreadyDefined(si.Name);
                        error = true;
                    }
                    else
                    {
                        info = CurrentScope.Add(si.Name);
                        info.Kind = SymbolTable.Information.EKind.Variable;
                        info.Properties["variable_arrayindices"] = new string[si.ArrayIndices.Count];
                        for (int i = 0; i < si.ArrayIndices.Count; ++i)
                            (info.Properties["variable_arrayindices"] as string[])[i] = si.ArrayIndices[i];
                        info.Properties["variable_type"] = si.Type;

                        // TODO: account for objects bigger than 4
                        //info.Properties.Add("variable_offset", CompilerStack.Peek().GetTotalRealOffset());
                    }
                }

                if (!error && p == 1)
                    Log(LogType.Parse, "<definition2> ::= <arraystar> ;");
            }

            return !error;
        }
Example #35
0
        // <statementstar> ::= e | <statement><statementstar>
        protected bool NTF_StatementStar(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, "if", "for", "cin", "cout", "return", Lexer.Token.TokenType.Identifier,
                Lexer.Token.TokenType.CloseBrace);

            // first(<statement>)=first(<variable>)+if+for+cin+cout+return
            //                   =first(<idnest>)+id+if+for+cin+cout+return
            //                   =id+if+for+cin+cout+return
            if (lookahead.Value == "if" || lookahead.Value == "for" || lookahead.Value == "cin" || lookahead.Value == "cout"
                || lookahead.Value == "return" || lookahead.Type == Lexer.Token.TokenType.Identifier)
            {
                error |= !NTF_Statement(p, si);
                error |= !NTF_StatementStar(p, si);

                if (!error && p == 1)
                    Log(LogType.Parse, "<statementstar> ::= <statement><statementstar>");
            }
            // follow(<statementstar>)=}
            else if (lookahead.Type == Lexer.Token.TokenType.CloseBrace)
            {
                if (p == 1)
                    Log(LogType.Parse, "<statementstar> ::= e");
            }
            else
                error = true;

            return !error;
        }
Example #36
0
        public override void CheckSemantic(SymbolTable symbolTable, List <CompileError> errors)
        {
            ///check semantics al CallableDeclarationNode
            base.CheckSemantic(symbolTable, errors);

            SemanticInfo returnTypeInfo;

            ///chequeamos si existe el tipo de retorno
            if (!symbolTable.GetDefinedTypeDeep(ReturnType, out returnTypeInfo))
            {
                errors.Add(new CompileError
                {
                    Line         = GetChild(ChildCount - 2).Line,
                    Column       = GetChild(ChildCount - 2).CharPositionInLine,
                    ErrorMessage = string.Format("Type '{0}' could not be found in current context", ReturnType),
                    Kind         = ErrorKind.Semantic
                });

                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
            }

            ///si CallableBody no evaluó de error y se encontró el tipo de retorno
            if (!Object.Equals(CallableBody.NodeInfo, SemanticInfo.SemanticError) &&
                !Object.Equals(returnTypeInfo, SemanticInfo.SemanticError))
            {
                ///el tipo deretorno del CallableBody tiene que ser compatible con el tipo de retorno
                if (!CallableBody.NodeInfo.Type.IsCompatibleWith(returnTypeInfo))
                {
                    errors.Add(new CompileError
                    {
                        Line         = GetChild(ChildCount - 2).Line,
                        Column       = GetChild(ChildCount - 2).CharPositionInLine,
                        ErrorMessage = string.Format("Cannot implicitly convert type '{0}' to '{1}'", CallableBody.NodeInfo.Type.Name, returnTypeInfo.Type.Name),
                        Kind         = ErrorKind.Semantic
                    });

                    ///el nodo evalúa de error
                    NodeInfo = SemanticInfo.SemanticError;
                }
            }

            ///si no ha evaluado de error le seteamos los valores
            if (!Object.Equals(NodeInfo, SemanticInfo.SemanticError))
            {
                NodeInfo = new SemanticInfo
                {
                    Name        = SemanticInfo.NoName,
                    ElementKind = SymbolKind.NoSymbol,
                    Type        = SemanticInfo.Void,
                    BuiltInType = BuiltInType.Void,
                    ILType      = returnTypeInfo.ILType
                };

                functionParche = returnTypeInfo;

                SemanticInfo arg;

                ///guardamos los ILType
                for (int i = 0; i < Parameters.Count; i++)
                {
                    symbolTable.GetDefinedTypeDeep(Parameters[i].Value, out arg);
                    ILTypes.Add(arg.ILType);
                }
            }

            SemanticInfo function;

            ///completamos la definición de la función
            symbolTable.GetDefinedCallableDeep(CallableId, out function);
            function.IsPending = false;
        }
Example #37
0
        private void _createFromAPIFormat(XElement elementXML, bool useNamespaces)
        {
            // смотрим что обрабатываем - слово или знак препинания
            var elementNode = elementXML.Element(XName.Get(Consts.NodeWord, Namespaces.NamespaceLinguistic));
            if (elementNode != null)
                ElementType = ComprenoSentenceElementType.ReadFromString(elementNode.Name.LocalName);
            else {
                elementNode = elementXML.Element(XName.Get(Consts.NodePunctuator, useNamespaces ? Namespaces.NamespaceLinguistic : ""));
                if (elementNode != null)
                    ElementType = ComprenoSentenceElementType.ReadFromString(elementNode.Element(XName.Get(Consts.NodePunctuatorType, useNamespaces ? Namespaces.NamespaceLinguistic : "")).Attribute(XName.Get(Consts.AttResourse, useNamespaces ? Namespaces.NamespaceRDF : "")).Value);
            }

            Debug.Assert(elementNode != null);
            Id = elementNode.Attribute(XName.Get(Consts.AttElementNodeId, useNamespaces ? Namespaces.NamespaceRDF : "")).Value;
            // проваливаемся на 1 уровень ниже - на нем располагаются все свойства
            elementXML = elementNode;

            var nodeIdName = XName.Get(Consts.AttElementNodeId, useNamespaces ? Namespaces.NamespaceRDF : "");

            // ChildTreeInit
            // вершиной дерева всегда будет ID слова
            ChildWordsIds.AddChild(Id);

            // Order
            var orderNodeName = XName.Get(Consts.NodeWordOrder, useNamespaces ? Namespaces.NamespaceLinguistic : "");
            Debug.Assert(elementXML.Element(orderNodeName) != null);
            Order = int.Parse(elementXML.Element(orderNodeName).Value);

            // Text
            var textNodeName = XName.Get(Consts.NodeWordText, useNamespaces ? Namespaces.NamespaceLinguistic : "");
            if (elementXML.Element(textNodeName) != null)
                Text = elementXML.Element(textNodeName).Value;
            else
                Text = "";

            // Lemma
            var lemmaNodeName = XName.Get(Consts.NodeLemmaName, useNamespaces ? Namespaces.NamespaceLinguistic : "");
            if (elementXML.Element(lemmaNodeName) != null)
                Lemma = elementXML.Element(lemmaNodeName).Value;
            else
                Lemma = "";

            // Syntactic Role
            var syntacticRoleNodeName = XName.Get(Consts.NodeSyntacticRole, useNamespaces ? Namespaces.NamespaceLinguistic : "");
            var syntacticRoleAttName = XName.Get(Consts.AttResourse, useNamespaces ? Namespaces.NamespaceRDF : "");
            if (elementXML.Element(syntacticRoleNodeName) != null)
                SyntacticRole = SyntacticRole.ReadFromString(elementXML.Element(syntacticRoleNodeName).Attribute(syntacticRoleAttName).Value);
            else
                SyntacticRole = SyntacticRole.Undefined;

            // Surface slot
            var surfaceSlotNodeName = XName.Get(Consts.NodeSurfaceSlot, useNamespaces ? Namespaces.NamespaceLinguistic : "");
            if (elementXML.Element(surfaceSlotNodeName) != null)
                SurfaceSlot = SurfaceSlot.ReadFromString(elementXML.Element(surfaceSlotNodeName).Value);
            else
                SurfaceSlot = SurfaceSlot.Undefined;

            // grammar info
            var grammarInfoNodeName = XName.Get(Consts.NodeGrammarInfo, useNamespaces ? Namespaces.NamespaceLinguistic : "");
            if (elementXML.Element(grammarInfoNodeName) != null)
                GrammarInfo = new GrammarInfo(elementXML.Element(grammarInfoNodeName), useNamespaces);
            else
                GrammarInfo = new GrammarInfo();

            // is restored
            var isRestoredNodeName = XName.Get(Consts.NodeIsRestored, useNamespaces ? Namespaces.NamespaceLinguistic : "");
            if (elementXML.Element(isRestoredNodeName) != null)
                IsRestored = (elementXML.Element(isRestoredNodeName).Value == Consts.ValueTrue);
            else
                IsRestored = false;

            //is word
            IsWord = ComprenoSentenceElementType.IsWord(ElementType);

            // syntactic parent id
            var syntacticParentNodeName = XName.Get(Consts.NodeSyntacticParent, useNamespaces ? Namespaces.NamespaceLinguistic : "");

            if (elementXML.Element(syntacticParentNodeName) != null)
                SyntacticParentWordId = elementXML.Element(syntacticParentNodeName).Attribute(nodeIdName).Value;
            else
                SyntacticParentWordId = "-1";

            // controller nodes
            var controllerNodeName = XName.Get(Consts.NodeHasController, useNamespaces ? Namespaces.NamespaceLinguistic : "");
            if (elementXML.Element(controllerNodeName) != null)
            {
                var singleControllerNodeName = XName.Get(Consts.NodeController, useNamespaces ? Namespaces.NamespaceLinguistic : "");
                foreach (var controllerItemXML in elementXML.Element(controllerNodeName).Elements(singleControllerNodeName))
                    ControllerNodes.Add(new Controller(controllerItemXML, useNamespaces));
            }

            // conjucted with
            var conjuctedWithNodeName = XName.Get(Consts.NodeConjuctedWith, useNamespaces ? Namespaces.NamespaceLinguistic : "");
            if (elementXML.Element(conjuctedWithNodeName) != null)
                ConjuctedWithId = elementXML.Element(conjuctedWithNodeName).Attribute(nodeIdName).Value;
            else
                ConjuctedWithId = "-1";

            // semantic info --> lexical class predefined
            var semanticInfoNodeName = XName.Get(Consts.NodeSemanticInfo, useNamespaces ? Namespaces.NamespaceLinguistic : "");
            SemanticInfo = new SemanticInfo(elementXML.Element(semanticInfoNodeName), useNamespaces);
        }
Example #38
0
        // <expr> ::= <arithexpr><expr2>
        protected bool NTF_Expr(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, "+", "-", Lexer.Token.TokenType.Identifier, Lexer.Token.TokenType.Number,
                Lexer.Token.TokenType.OpenBracket, Lexer.Token.TokenType.Not,
                Lexer.Token.TokenType.Semicolon, Lexer.Token.TokenType.CloseBracket);

            error |= !NTF_ArithExpr(p, si);
            error |= !NTF_Expr2(p, si);

            if (!error && p == 1)
                Log(LogType.Parse, "<expr> ::= <arithexpr> <expr2>");

            return !error;
        }
Example #39
0
        // <statement> ::= <variable> := <expr>
        //               | if ( <expr> ) then <statblock> else <statblock> fi ;
        //               | for ( <statement> ; <expr> ; <statement> ) <statblock> ;
        //               | cin ( <variable> ) ;
        //               | cout ( <expr> ) ;
        //               | return ( <expr> ) ;
        protected bool NTF_Statement(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, Lexer.Token.TokenType.Identifier, "if", "for", "cin", "cout", "return",
                Lexer.Token.TokenType.CloseBrace, Lexer.Token.TokenType.Semicolon, "else", "fi");

            SemanticInfo si2, si3, si4, si5;

            // first(<variable>)
            if (lookahead.Type == Lexer.Token.TokenType.Identifier)
            {
                si2 = new SemanticInfo();
                error |= !NTF_Variable(p, si2);
                error |= !Match(p, Lexer.Token.TokenType.Assignement);
                si3 = new SemanticInfo();
                error |= !NTF_Expr(p, si3);
                error |= !Match(p, Lexer.Token.TokenType.Semicolon);

                if (p == 2)
                {
                    // check to see if the types match
                    if (si2.Type != si3.Type)
                        SemanticErrorWrongTypeExpected(si3.Type, si2.Type);

                    // paste si3.code and store the offset, after which you free the temp var if necessary
                    si.Code.Append(si3.Code);
                    si.Code.Append("addi r1,r14," + si3.Offset + "\nlw r2,stack(r1)\naddi r1,r14," + si2.Offset +
                        "\nsw stack(r1), r2\n");
                }

                if (!error && p == 1)
                    Log(LogType.Parse, "<statement> ::= <variable> := <expr>");
            }
            else if (lookahead.Value == "if")
            {
                error |= !Match(p, "if");
                error |= !Match(p, Lexer.Token.TokenType.OpenBracket);
                si2 = new SemanticInfo();
                error |= !NTF_Expr(p, si2);
                error |= !Match(p, Lexer.Token.TokenType.CloseBracket);
                error |= !Match(p, "then");
                si3 = new SemanticInfo();
                error |= !NTF_StatBlock(p, si3);
                error |= !Match(p, "else");
                si4 = new SemanticInfo();
                error |= !NTF_StatBlock(p, si4);
                error |= !Match(p, "fi");
                error |= !Match(p, Lexer.Token.TokenType.Semicolon);

                if (p == 2)
                {
                    // test expression
                    si.Code.Append(si2.Code);

                    // jump
                    string j1 = GetNewJumpLabel();
                    si.Code.Append("addi r2,r14," + si2.Offset + "\nlw r1,stack(r2)\nbz r1, " + j1 + "\n");

                    // then code
                    si.Code.Append(si3.Code);

                    // exit if
                    string j2 = GetNewJumpLabel();
                    si.Code.Append("j " + j2 + "\n");

                    // else code
                    si.Code.Append(j1 + " nop\n");
                    si.Code.Append(si4.Code);

                    // finish up
                    si.Code.Append(j2 + " nop\n");
                }

                if (!error && p == 1)
                    Log(LogType.Parse, "<statement> ::= if ( <expr> ) then <statblock> else <statblock> fi ;");
            }
            else if (lookahead.Value == "for")
            {
                error |= !Match(p, "for");
                error |= !Match(p, Lexer.Token.TokenType.OpenBracket);
                si2 = new SemanticInfo();
                error |= !NTF_Statement(p, si2);
                error |= !Match(p, Lexer.Token.TokenType.Semicolon);
                si3 = new SemanticInfo();
                error |= !NTF_Expr(p, si3);
                error |= !Match(p, Lexer.Token.TokenType.Semicolon);
                si4 = new SemanticInfo();
                error |= !NTF_Statement(p, si4);
                error |= !Match(p, Lexer.Token.TokenType.CloseBracket);
                si5 = new SemanticInfo();
                error |= !NTF_StatBlock(p, si5);
                error |= !Match(p, Lexer.Token.TokenType.Semicolon);

                if (p == 2)
                {
                    // init
                    si.Code.Append(si2.Code);

                    // add the label
                    string j1 = GetNewJumpLabel();
                    si.Code.AppendLine(j1 + " nop");

                    // test
                    si.Code.Append(si3.Code);
                    string j2 = GetNewJumpLabel();
                    si.Code.AppendLine("addi r2,r14," + si3.Offset + "\nlw r1,stack(r2)\nbz r1," + j2);

                    // statements and increment
                    si.Code.Append(si5.Code);
                    si.Code.Append(si4.Code);

                    // jump back to the test
                    si.Code.AppendLine("j " + j1);

                    // exit label
                    si.Code.AppendLine(j2 + " nop");
                }

                if (!error && p == 1)
                    Log(LogType.Parse, "<statement> ::= for ( <statement> ; <expr> ; <statement> ) <statblock> ;");
            }
            else if (lookahead.Value == "cin")
            {
                error |= !Match(p, "cin");
                error |= !Match(p, Lexer.Token.TokenType.OpenBracket);
                si2 = new SemanticInfo();
                error |= !NTF_Variable(p, si2);
                error |= !Match(p, Lexer.Token.TokenType.CloseBracket);
                error |= !Match(p, Lexer.Token.TokenType.Semicolon);

                if (p == 2)
                {
                    int[] tmp = CompilerStack.Peek().GenerateBackupRegisters(si.Code);
                    si.Code.Append("jl r15,getint\naddi r2,r14," + si2.Offset + "\nsw stack(r2),r1\n");
                    CompilerStack.Peek().GenerateRestoreRegisters(si.Code, tmp);
                }

                if (!error && p == 1)
                    Log(LogType.Parse, "<statement> ::= cin ( <variable> ) ;");
            }
            else if (lookahead.Value == "cout")
            {
                error |= !Match(p, "cout");
                error |= !Match(p, Lexer.Token.TokenType.OpenBracket);
                si2 = new SemanticInfo();
                error |= !NTF_Expr(p, si2);
                error |= !Match(p, Lexer.Token.TokenType.CloseBracket);
                error |= !Match(p, Lexer.Token.TokenType.Semicolon);

                if (p == 2)
                {
                    // append si2 and load the temp register into r1 before calling cout
                    si.Code.Append(si2.Code);
                    int[] tmp = CompilerStack.Peek().GenerateBackupRegisters(si.Code);
                    si.Code.Append("addi r2,r14," + si2.Offset + "\nlw r1,stack(r2)\n");
                    si.Code.Append("jl r15,putint\n");
                    CompilerStack.Peek().GenerateRestoreRegisters(si.Code, tmp);
                }

                if (!error && p == 1)
                    Log(LogType.Parse, "<statement> ::= cout ( <expr> ) ;");
            }
            else if (lookahead.Value == "return")
            {
                error |= !Match(p, "return");
                error |= !Match(p, Lexer.Token.TokenType.OpenBracket);
                si2 = new SemanticInfo();
                error |= !NTF_Expr(p, si2);
                error |= !Match(p, Lexer.Token.TokenType.CloseBracket);
                error |= !Match(p, Lexer.Token.TokenType.Semicolon);

                if (p == 2)
                {
                    si.Code.Append(si2.Code);
                    // store the return in r1
                    // make sure the return type matches
                    SymbolTable.Information info = CurrentScope.Parent.Find(CurrentScope.ID, false);
                    if (info.Properties["function_type"] as string != si2.Type)
                    {
                        error = true;
                        SemanticErrorWrongReturnTypeExpected
                            (si.Name, si2.Type, info.Properties["function_type"] as string);
                    }
                    else
                    {
                        // copy it in r1
                        si.Code.Append("addi r2,r14," + si2.Offset + "\nlw r1,stack(r2)\njr r15\n");
                    }
                }

                if (!error && p == 1)
                    Log(LogType.Parse, "<statement> ::= return ( <expr> ) ;");
            }
            else
                error = true;

            return !error;
        }
Example #40
0
        /// <summary>
        /// The main function. Runs the parser over the stream and 
        /// returns whether or not the stream is valid.
        /// </summary>
        /// <returns>A bool indicating whether or not the stream is valid syntactically</returns>
        public bool Parse()
        {
            // first parse the program
            // phase 1
            CompilerStack.Clear();
            CompilerStack.Push(new StackFrame(this));
            lexer.Reset();
            lookahead = lexer.GetNextToken();
            SemanticInfo si = new SemanticInfo();
            bool ok1 = NTF_Prog(1, si) && Match(1, Lexer.Token.TokenType.EndOfFile);

            ComputeClassSizes();

            // phase 2
            CompilerStack.Clear();
            CompilerStack.Push(new StackFrame(this));
            si = new SemanticInfo();
            lexer.Reset();
            lookahead = lexer.GetNextToken();
            bool ok2 = NTF_Prog(2, si) && Match(2, Lexer.Token.TokenType.EndOfFile);

            si.Code.Insert(0, "stack res 5000\nalign\n");
            si.Code.Append(
            @"
            putint	align
            add	r2,r0,r0		% Initialize buffer's index i
            cge	r3,r1,r0		% True if N >= 0
            bnz	r3,putint1		% Branch if True (N >= 0)
            sub	r1,r0,r1		% N = -N
            putint1	modi	r4,r1,10		% Rightmost digit
            addi	r4,r4,48		% Convert to ch
            divi	r1,r1,10		% Truncate rightmost digit
            sb	putint9(r2),r4		% Store ch in buffer
            addi	r2,r2,1			% i++
            bnz	r1,putint1		% Loop if not finished
            bnz	r3,putint2		% Branch if True (N >= 0)
            addi	r3,r0,45
            sb	putint9(r2),r3		% Store '-' in buffer
            addi	r2,r2,1			% i++
            add	r1,r0,r0		% Initialize output register (r1 = 0)
            putint2	subi	r2,r2,1			% i--
            lb	r1,putint9(r2)		% Load ch from buffer
            putc	r1			% Output ch
            bnz	r2,putint2		% Loop if not finished
            addi r1,r0,13       % load new line
            putc r1             % print it
            addi r1,r0,10       % new feed thingie
            putc r1
            jr	r15			% return to the caller
            putint9	res	12			% loacl buffer (12 bytes)
            align

            getint   add    r1,r0,r0         % n := 0 (result)
             add    r2,r0,r0         % c := 0 (character)
             add    r3,r0,r0         % s := 0 (sign)
            getint1  getc   r2               % read c
             ceqi   r4,r2,32
             bnz    r4,getint1       % skip blanks
             ceqi   r4,r2,43
             bnz    r4,getint2       % branch if c is '+'
             ceqi   r4,r2,45
             bz     r4,getint3       % branch if c is not '-'
             addi   r3,r0,1          % s := 1 (number is negative)
            getint2  getc   r2               % read c
            getint3  ceqi   r4,r2,10
             bnz    r4,getint5       % branch if c is \n
             cgei   r4,r2,48
             bz     r4,getint4       % c < 0
             clei   r4,r2,57
             bz     r4,getint4       % c > 9
             muli   r1,r1,10         % n := 10 * n
             add    r1,r1,r2         % n := n + c
             subi   r1,r1,48         % n := n - '0'
             j      getint2
            getint4  addi   r2,r0,63         % c := '?'
             putc   r2               % write c
             j      getint           % Try again
            getint5  bz     r3,getint6       % branch if s = 0 (number is positive)
             sub    r1,r0,r1         % n := -n
            getint6  jr     r15              % return
            ");

            Log(LogType.Code, si.Code.ToString());

            // then write out the debug information
            Log(LogType.SymbolTable, Global.ToString());

            foreach (string error in Errors)
                Log(LogType.Error, error);

            foreach (string warning in Warnings)
                Log(LogType.Warning, warning);

            // and flush the streams
            foreach (TextWriter tw in Output.Values)
                tw.Flush();

            return ok1 && ok2;
        }
Example #41
0
        public override void CheckSemantic(SymbolTable symbolTable, List <CompileError> errors)
        {
            ///check semantics al StartIndex
            StartIndex.CheckSemantic(symbolTable, errors);

            ///check semantics al EndIndex
            EndIndex.CheckSemantic(symbolTable, errors);

            ///si StartIndex no evaluó de error
            if (!Object.Equals(StartIndex.NodeInfo, SemanticInfo.SemanticError))
            {
                ///la expresión de StartIndex tiene que ser compatible con 'int'
                if (!StartIndex.NodeInfo.BuiltInType.IsCompatibleWith(BuiltInType.Int))
                {
                    errors.Add(new CompileError
                    {
                        Line         = StartIndex.Line,
                        Column       = StartIndex.CharPositionInLine,
                        ErrorMessage = string.Format("Cannot implicitly convert type '{0}' to 'int'", StartIndex.NodeInfo.Type.Name),
                        Kind         = ErrorKind.Semantic
                    });

                    ///el nodo evalúa de error
                    NodeInfo = SemanticInfo.SemanticError;
                }
            }

            ///si EndIndex no evaluó de error
            if (!Object.Equals(EndIndex.NodeInfo, SemanticInfo.SemanticError))
            {
                ///la expresión de EndIndex tiene que ser compatible con 'int'
                if (!EndIndex.NodeInfo.BuiltInType.IsCompatibleWith(BuiltInType.Int))
                {
                    errors.Add(new CompileError
                    {
                        Line         = EndIndex.Line,
                        Column       = EndIndex.CharPositionInLine,
                        ErrorMessage = string.Format("Cannot implicitly convert type '{0}' to 'int'", EndIndex.NodeInfo.Type.Name),
                        Kind         = ErrorKind.Semantic
                    });

                    ///el nodo evalúa de error
                    NodeInfo = SemanticInfo.SemanticError;
                }
            }

            SemanticInfo loopVarInfo;

            ///no puede haber otra variable con el mismo nombre que este
            if (symbolTable.GetDefinedVariableDeep(LoopVariable, out loopVarInfo))
            {
                errors.Add(new CompileError
                {
                    Line         = GetChild(0).Line,
                    Column       = GetChild(0).CharPositionInLine,
                    ErrorMessage = string.Format("A local variable named '{0}' cannot be declared in this scope because it would give a different meaning to'{1}', which is already used in a 'parent or current' scope to denote something else", LoopVariable, LoopVariable),
                    Kind         = ErrorKind.Semantic
                });
            }

            ///creamos un nuevo scope
            symbolTable.InitNewScope();

            ///agregamos la variable de iteración al scope actual
            SemanticInfo loopVariable = new SemanticInfo
            {
                Name        = LoopVariable,
                ElementKind = SymbolKind.Variable,
                IsReadOnly  = true,             //ponemos la variable como readonly
                BuiltInType = BuiltInType.Int,
                Type        = SemanticInfo.Int
            };

            symbolTable.InsertSymbol(loopVariable);

            ///check semantics al ForBody
            ForBody.CheckSemantic(symbolTable, errors);

            ///aquí concluye el scope que crea el for
            symbolTable.CloseCurrentScope();

            ///si el ForBody evalúa de error este también
            if (Object.Equals(ForBody.NodeInfo, SemanticInfo.SemanticError))
            {
                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
                return;
            }

            ///seteamos la información del NodeInfo
            NodeInfo.BuiltInType = BuiltInType.Void;
            NodeInfo.Type        = SemanticInfo.Void;

            ///el ForBody no puede retornar valor
            if (ForBody.NodeInfo.BuiltInType.IsReturnType())
            {
                errors.Add(new CompileError
                {
                    Line         = ForBody.Line,
                    Column       = ForBody.CharPositionInLine,
                    ErrorMessage = "Body of control instruction 'for' cannot return value",
                    Kind         = ErrorKind.Semantic
                });

                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
            }
        }
Example #42
0
        // <expr2> ::= e | relop <arithexpr>
        protected bool NTF_Expr2(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, Lexer.Token.TokenType.Comparison,
                Lexer.Token.TokenType.Semicolon, Lexer.Token.TokenType.CloseBracket);

            // first(<expr2>)=relop
            if (lookahead.Type == Lexer.Token.TokenType.Comparison)
            {
                string op = lookahead.Value;
                if (op == "<") op = "clt";
                else if (op == "<=") op = "cle";
                else if (op == ">") op = "cgt";
                else if (op == ">=") op = "cge";
                else if (op == "==") op = "ceq";
                else if (op == "<>") op = "cne";
                error |= !Match(p, Lexer.Token.TokenType.Comparison);
                SemanticInfo si2 = new SemanticInfo();
                error |= !NTF_ArithExpr(p, si2);

                if (p == 2)
                {
                    si.Code.Append(si2.Code);
                    si.Code.Append("addi r3,r14," + si.Offset + "\nlw r1,stack(r3)\n" +
                        "addi r3,r14," + si2.Offset + "\nlw r2,stack(r3)\n" + op + " r1,r1,r2\n");

                    CompilerStack.Peek().SafeFreeTemp(si.Offset);
                    CompilerStack.Peek().SafeFreeTemp(si2.Offset);

                    int tmp = CompilerStack.Peek().RequestTemp() + CompilerStack.Peek().GetTotalRealOffset();
                    si.Code.Append("addi r2,r14," + tmp + "\nsw stack(r2),r1\n");
                    si.Offset = tmp;
                }

                if (!error && p == 1)
                    Log(LogType.Parse, "<expr2> ::= relop <arithexpr>");
            }
            // follow(<expr2>)=follow(<expr>)=;+)
            else if (lookahead.Type == Lexer.Token.TokenType.Semicolon || lookahead.Type == Lexer.Token.TokenType.CloseBracket)
            {
                if (p == 1)
                    Log(LogType.Parse, "<expr2> ::= e");
            }
            else
                error = true;

            return !error;
        }
Example #43
0
        // <sign> ::= + | -
        protected bool NTF_Sign(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, "+", "-",
                Lexer.Token.TokenType.Identifier, Lexer.Token.TokenType.Number, Lexer.Token.TokenType.OpenBracket,
                Lexer.Token.TokenType.Not);

            if (lookahead.Value == "+")
            {
                error |= !Match(p, "+");

                if (!error && p == 1)
                    Log(LogType.Parse, "<sign> ::= +");
            }
            else
            {
                error |= !Match(p, "-");

                // TODO: fix unary -
                if (p == 2)
                    SemanticError("unary - not working yet");

                if (!error && p == 1)
                    Log(LogType.Parse, "<sign> ::= -");
            }

            return false;
        }
Example #44
0
        // <factor> ::= <idnest> <factor2>
        //            | num
        //            | ( <expr> )
        //            | ! <factor>
        protected bool NTF_Factor(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, Lexer.Token.TokenType.Identifier, Lexer.Token.TokenType.Number, Lexer.Token.TokenType.OpenBracket,
                Lexer.Token.TokenType.Not, Lexer.Token.TokenType.Multiplicative, Lexer.Token.TokenType.Comparison,
                Lexer.Token.TokenType.Additive, Lexer.Token.TokenType.Comma, Lexer.Token.TokenType.CloseBracket,
                Lexer.Token.TokenType.Semicolon);

            // first(<idneststar>)=id
            if (lookahead.Type == Lexer.Token.TokenType.Identifier)
            {
                error |= !NTF_IdNest(p, si);
                error |= !NTF_Factor2(p, si);

                if (!error && p == 1)
                    Log(LogType.Parse, "<factor> ::= <idneststar> id <factor2>");
            }
            else if (lookahead.Type == Lexer.Token.TokenType.Number)
            {
                if (p == 2)
                {
                    // load the number
                    si.Name = lookahead.Value;
                    si.Type = lookahead.Value.IndexOf('.') >= 0 ? "float" : "int";
                    // TODO: make it work with floats
                    si.Offset = CompilerStack.Peek().GetTotalRealOffset() + CompilerStack.Peek().RequestTemp();
                    si.Code.Append("addi r1,r0," + lookahead.Value + "\naddi r2,r14," + si.Offset + "\nsw stack(r2),r1\n");
                }
                error |= !Match(p, Lexer.Token.TokenType.Number);

                if (!error && p == 1)
                    Log(LogType.Parse, "<factor> ::= num");
            }
            else if (lookahead.Type == Lexer.Token.TokenType.OpenBracket)
            {
                error |= !Match(p, Lexer.Token.TokenType.OpenBracket);
                error |= !NTF_Expr(p, si);
                error |= !Match(p, Lexer.Token.TokenType.CloseBracket);

                if (!error && p == 1)
                    Log(LogType.Parse, "<factor> ::= ( <expr> )");
            }
            else if (lookahead.Type == Lexer.Token.TokenType.Not)
            {
                error |= !Match(p, Lexer.Token.TokenType.Not);

                SemanticInfo si2 = new SemanticInfo();
                error |= !NTF_Factor(p, si2);

                if (p == 2)
                {
                    si.Code.Append(si2.Code);
                    si.Code.Append("addi r2,r14," + si2.Offset + "\nlw r1,stack(r2)\nnot r1,r1\n");
                    CompilerStack.Peek().SafeFreeTemp(si2.Offset);

                    string jmp_zero = GetNewJumpLabel();
                    si.Code.Append("bz r1," + jmp_zero + "\naddi r1,r0,1\n" + jmp_zero + " nop\n");

                    si.Offset = CompilerStack.Peek().RequestTemp();
                    si.Code.Append("addi r2,r14," + si.Offset + "\nsw stack(r2),r1\n");
                }

                if (!error && p == 1)
                    Log(LogType.Parse, "<factor> ::= ! <factor>");
            }
            else
                error = true;

            return !error;
        }
Example #45
0
        // <prog> ::= <classdeclstar><progbody>
        protected bool NTF_Prog(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, "class", "program", Lexer.Token.TokenType.EndOfFile);

            error |= !NTF_ClassDeclStar(p, si);
            error |= !NTF_ProgBody(p, si);

            if (!error && p == 1)
                Log(LogType.Parse, "<prog> ::= <classdeclstar><progbody>");

            return !error;
        }
Example #46
0
        public override void CheckSemantic(SymbolTable symbolTable, List <CompileError> errors)
        {
            ///la instrucción let-in-end genera un nuevo scope
            symbolTable.InitNewScope();

            #region CheckSemantic_of_Declarations_List

            DeclarationNode        currentDeclaration;
            DeclarationType        previousDeclarationType = DeclarationType.NONE;
            List <DeclarationNode> pendingDeclarations     = new List <DeclarationNode>();

            ///chequeamos la semántica de C/U de las declaraciones
            for (int i = 0; i < LetDeclarationCount; i++)
            {
                currentDeclaration = GetLetDeclarationAt(i);

                if (GetDeclarationType(currentDeclaration) != previousDeclarationType && pendingDeclarations.Count > 0)
                {
                    CommitPendingDeclarations(symbolTable, errors, pendingDeclarations);
                    pendingDeclarations.Clear();
                }

                if (GetDeclarationType(currentDeclaration) == DeclarationType.VARIABLE)
                {
                    currentDeclaration.CheckSemantic(symbolTable, errors);
                }
                else
                {
                    pendingDeclarations.Add(currentDeclaration);
                }

                previousDeclarationType = GetDeclarationType(currentDeclaration);
            }

            ///chequeamos el último bloque
            if (pendingDeclarations.Count > 0)
            {
                CommitPendingDeclarations(symbolTable, errors, pendingDeclarations);
                pendingDeclarations.Clear();
            }
            #endregion

            ///chequeamos la semántica de ExpressionSequence
            ExpressionSequence.CheckSemantic(symbolTable, errors);

            ///si el ExpressionSequence evalúa de error, este también
            if (Object.Equals(ExpressionSequence.NodeInfo, SemanticInfo.SemanticError))
            {
                ///el nodo evalúa de error
                NodeInfo = SemanticInfo.SemanticError;
            }

            ///el scope de let-in-end termina en el end
            symbolTable.CloseCurrentScope();

            ///si este no evaluó de error
            if (!Object.Equals(NodeInfo, SemanticInfo.SemanticError))
            {
                NodeInfo = new SemanticInfo
                {
                    Name        = SemanticInfo.NoName,
                    BuiltInType = ExpressionSequence.NodeInfo.BuiltInType,
                    ElementKind = SymbolKind.NoSymbol,
                    Type        = ExpressionSequence.NodeInfo.Type,

                    ElementsType = ExpressionSequence.NodeInfo.ElementsType,
                    Fields       = ExpressionSequence.NodeInfo.Fields,

                    //added
                    ILType = ExpressionSequence.NodeInfo.ILType
                };
            }
        }
        private static SemanticInfo ExtractSemanticInfo(Type modelType)
        {
            SemanticInfo semanticInfo = new SemanticInfo();

            // Built-in semantic type mapping
            string bareTypeName = modelType.Name.Split('`')[0]; // Type name without generic type parameters (if any)
            semanticInfo.MappedSemanticTypes.Add(SemanticMapping.GetQualifiedTypeName(bareTypeName));

            // Extract semantic info from SemanticEntity attributes on the Model Type.
            foreach (SemanticEntityAttribute attribute in modelType.GetCustomAttributes(true).Where(a => a is SemanticEntityAttribute))
            {
                semanticInfo.MappedSemanticTypes.Add(SemanticMapping.GetQualifiedTypeName(attribute.EntityName, attribute.Vocab));

                if (!attribute.Public || string.IsNullOrEmpty(attribute.Prefix))
                    continue;

                string prefix = attribute.Prefix;
                string registeredVocab;
                if (semanticInfo.PrefixMappings.TryGetValue(prefix, out registeredVocab))
                {
                    // Prefix mapping already exists; must match.
                    if (attribute.Vocab != registeredVocab)
                    {
                        throw new DxaException(
                            string.Format("Attempt to use semantic prefix '{0}' for vocabulary '{1}', but is is already used for vocabulary '{2}",
                                prefix, attribute.Vocab, registeredVocab)
                            );
                    }
                }
                else
                {
                    semanticInfo.PrefixMappings.Add(prefix, attribute.Vocab);
                }

                semanticInfo.PublicSemanticTypes.Add(String.Format("{0}:{1}", prefix, attribute.EntityName));
            }

            // Extract semantic info from SemanticEntity attributes on the Model Type's properties
            foreach (MemberInfo memberInfo in modelType.GetMembers(BindingFlags.Public | BindingFlags.Instance))
            {
                foreach (SemanticPropertyAttribute attribute in memberInfo.GetCustomAttributes(true).Where(a => a is SemanticPropertyAttribute))
                {
                    if (string.IsNullOrEmpty(attribute.PropertyName))
                    {
                        // Skip properties without name.
                        continue;
                    }
                    string[] semanticPropertyNameParts = attribute.PropertyName.Split(':');
                    if (semanticPropertyNameParts.Length < 2)
                    {
                        // Skip property names without prefix.
                        continue;
                    }
                    string prefix = semanticPropertyNameParts[0];
                    if (!semanticInfo.PrefixMappings.ContainsKey(prefix))
                    {
                        // Skip property names with prefix which is not declared as public prefix on the type.
                        continue;
                    }

                    IList<string> semanticPropertyNames;
                    if (!semanticInfo.SemanticProperties.TryGetValue(memberInfo.Name, out semanticPropertyNames))
                    {
                        semanticPropertyNames = new List<string>();
                        semanticInfo.SemanticProperties.Add(memberInfo.Name, semanticPropertyNames);
                    }
                    semanticPropertyNames.Add(attribute.PropertyName);
                }
            }

            return semanticInfo;
        }
Example #48
0
        // <type> ::= int | float | id
        protected bool NTF_Type(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, "int", "float", Lexer.Token.TokenType.Identifier);

            if (lookahead.Value == "int")
            {
                si.Type = "int";
                error |= !Match(p, "int");

                if (!error && p == 1)
                    Log(LogType.Parse, "<type> ::= int");
            }
            else if (lookahead.Value == "float")
            {
                si.Type = "float";
                error |= !Match(p, "float");

                if (!error && p == 1)
                    Log(LogType.Parse, "<type> ::= float");
            }
            else if (lookahead.Type == Lexer.Token.TokenType.Identifier)
            {
                si.Type = lookahead.Value;
                error |= !Match(p, Lexer.Token.TokenType.Identifier);

                if (!error && p == 1)
                    Log(LogType.Parse, "<type> ::= id");
            }

            return !error;
        }
Example #49
0
        // <definitionstar> ::= e | <definition> <definitionstar>
        protected bool NTF_DefinitionStar(int p, SemanticInfo si)
        {
            bool error = SkipErrors(p, "int", "float", Lexer.Token.TokenType.Identifier, Lexer.Token.TokenType.CloseBrace,
                Lexer.Token.TokenType.EndOfFile);

            if (lookahead.Value == "int" || lookahead.Value == "float" || lookahead.Type == Lexer.Token.TokenType.Identifier)
            {
                error |= !NTF_Definition(p, si);
                error |= !NTF_DefinitionStar(p, si);

                if (!error && p == 1)
                    Log(LogType.Parse, "<definitionstar> ::= <definition> <definitionstar>");
            }
            // follow=}+$
            else if (lookahead.Type == Lexer.Token.TokenType.EndOfFile || lookahead.Type == Lexer.Token.TokenType.CloseBrace)
            {
                if (p == 1)
                    Log(LogType.Parse, "<definitionstar> ::= e");
            }
            else
                error = true;

            return !error;
        }
Example #50
0
        // <typedecl> ::= <type> id <arraystar>;
        protected bool NTF_TypeDecl(int p)
        {
            bool error = SkipErrors(p, "int", "float", Lexer.Token.TokenType.Identifier,
                "if", "cin", "cout", "return", "for", Lexer.Token.TokenType.CloseBrace);

            SemanticInfo si = new SemanticInfo();

            error |= !NTF_Type(p, si);
            si.Name = lookahead.Value;
            error |= !Match(p, Lexer.Token.TokenType.Identifier);
            error |= !NTF_ArrayStar(p, si);
            error |= !Match(p, Lexer.Token.TokenType.Semicolon);

            if (p == 1)
            {
                SymbolTable.Information info;
                if ((info = CurrentScope.Find(si.Name, false)) != null)
                    SemanticErrorSymbolAlreadyDefined(si.Name);
                else
                {
                    info = CurrentScope.Add(si.Name);
                    info.Kind = SymbolTable.Information.EKind.Variable;
                    info.Properties.Add("variable_type", si.Type);
                    info.Properties.Add("variable_arrayindices", si.ArrayIndices.ToArray());

                    // TODO: account for objects bigger than 4 (word)
                    //info.Properties.Add("variable_offset", CompilerStack.Peek().GetTotalRealOffset());
                }
            }

            if (!error && p == 1)
                Log(LogType.Parse, "<typedecl> ::= <type> id <arraystar>;");

            return !error;
        }