Esempio n. 1
0
 /// <summary>
 /// Считается ли данная лексема логическим сравнением?
 /// <, >, <=, >=, ==, !=
 /// </summary>
 public static bool isLogicCompare(LexemKind kind)
 {
     return(kind == LexemKind.LESSER ||
            kind == LexemKind.GREATER ||
            kind == LexemKind.LESSER_EQUALS ||
            kind == LexemKind.GREATER_EQUALS ||
            kind == LexemKind.EQUALS ||
            kind == LexemKind.NOTEQUALS);
 }
Esempio n. 2
0
        /// <summary>
        /// Пропарсить синтаксический примитив
        /// (любой литерал, унарные операции и просто переменные или вызовы функций)
        /// </summary>
        /// <param name="lexems">список лексем примитива</param>
        private static ICommand parsePrimitive(List <Lexem> lexems)
        {
            if (lexems.Count == 0)
            {
                return(null);
            }

            LexemKind kind = lexems[0].kind;

            if (kind == LexemKind.NOT)
            {
                lexems.RemoveAt(0);
                return(new CommandUnary(parsePrimitive(lexems), LexemKind.NOT));
            }
            else if (kind == LexemKind.BRACE && lexems.Count == 1)
            {
                return(parseStatement(lexems[0].childs));
            }
            else if (kind == LexemKind.NUMBER && lexems.Count == 1)
            {
                return(new CommandNumeric(int.Parse(lexems[0].value)));
            }
            else if (kind == LexemKind.STRING && lexems.Count == 1)
            {
                return(new CommandString(lexems[0].value));
            }
            else if (kind == LexemKind.STRING_VARIABLED && lexems.Count == 1)
            {
                return(new CommandStringVariabled(lexems[0].value));
            }
            else if (kind == LexemKind.TRUE && lexems.Count == 1)
            {
                return(new CommandBool(true));
            }
            else if (kind == LexemKind.FALSE && lexems.Count == 1)
            {
                return(new CommandBool(false));
            }
            else if (kind == LexemKind.IDENTIFIER)
            {
                return(parseNamedPrimitive(lexems));
            }
            else if (kind == LexemKind.INCREMENT || kind == LexemKind.DECREMENT)
            {
                lexems.RemoveAt(0);
                if (lexems.Count == 1 && lexems[0].kind == LexemKind.IDENTIFIER)
                {
                    return(new CommandUnary(new CommandVariable(lexems[0].value), kind));
                }
            }
            throw new InvalidOperationException("Неизвестный синтаксический примитив! " + string.Join(", ", lexems.Select(s => s.kind.ToString()).ToArray()));
        }
Esempio n. 3
0
 protected Lexem(LexemKind kind)
 {
     Kind = kind;
 }
Esempio n. 4
0
		private bool Check(LexemKind lexem, int lexemId)
		{
			var lex = Lexems[lexemId];
			
			if (lex.Kind != lexem)
				return false;

			return true;
		}
Esempio n. 5
0
		private bool Ensure(int lexemId, LexemKind type, string msg, params object[] args)
		{
			var lex = Lexems[lexemId];
			if(lex.Kind != type)
			{
				error(msg, lexemId, args);
				return false;
			}

			return true;
		}
Esempio n. 6
0
		GLRCommandTree CreateVariable(LexemKind LexemType, Type CLRType)
		{
			if(Lexems[LexemId].Kind == LexemType
			   && Ensure(LexemId+1, LexemKind.Identifier, "Ожидается имя переменной!")
			   && Ensure(LexemId+2, LexemKind.Semicolon, "Ожидается точка с запятой!")
			   )
			{
				GameLanguageRuntime.CreateVariableCommand command = new GameLanguageRuntime.CreateVariableCommand();
				command.VariableType = CLRType;
				command.VariableName = Lexems[LexemId+1].Value;
				
				if(createdVariables.ContainsKey(command.VariableName))
					error("Переменная {0} уже объявленна", LexemId+1, Lexems[LexemId+1].Value);
				else
					createdVariables.Add(command.VariableName,CLRType);
				
				LexemId+=3;
				
				GLRCommandTree tree = new GLRCommandTree();
				tree.Value = command;
				return tree;
			}
			return null;
		}
Esempio n. 7
0
 protected Lexem(LexemKind kind)
 {
     Kind = kind;
 }
Esempio n. 8
0
        /// <summary>
        /// Парсит математическое или логическое выражение, разделённое
        /// при помощи +, -, *, /, логическое сравнение, &&, ||.
        /// Делит выражение рекурсивно по этапам, компонуя разделённые части на каждом этапе
        /// определённой командой (например, CommandMath)
        /// </summary>
        /// <param name="lexems">список лексем, который нужно разделить</param>
        /// <param name="level">уровень деления</param>
        private static ICommand parseCommandPart(List <Lexem> lexems, int level)
        {
            if (level >= 7)
            {
                return(parsePrimitive(lexems));
            }

            int count = 1;
            List <List <Lexem> > list        = new List <List <Lexem> >();
            LexemKind            compareKind = LexemKind.UNKNOWN;
            List <Lexem>         buffer      = new List <Lexem>();

            foreach (Lexem lexem in lexems)
            {
                if (level == 0)
                {
                    if (lexem.kind == LexemKind.AND)
                    {
                        count++;
                        list.Add(buffer);
                        buffer = new List <Lexem>();
                        continue;
                    }
                }
                else if (level == 1)
                {
                    if (lexem.kind == LexemKind.OR)
                    {
                        count++;
                        list.Add(buffer);
                        buffer = new List <Lexem>();
                        continue;
                    }
                }
                else if (level == 2)
                {
                    if (LexemDefinitions.isLogicCompare(lexem.kind))
                    {
                        count++;
                        list.Add(buffer);
                        buffer      = new List <Lexem>();
                        compareKind = lexem.kind;
                        continue;
                    }
                }
                else if (level == 3)
                {
                    if (lexem.kind == LexemKind.PLUS)
                    {
                        count++;
                        list.Add(buffer);
                        buffer = new List <Lexem>();
                        continue;
                    }
                }
                else if (level == 4)
                {
                    if (lexem.kind == LexemKind.MINUS)
                    {
                        count++;
                        list.Add(buffer);
                        buffer = new List <Lexem>();
                        continue;
                    }
                }
                else if (level == 5)
                {
                    if (lexem.kind == LexemKind.MULTIPLY)
                    {
                        count++;
                        list.Add(buffer);
                        buffer = new List <Lexem>();
                        continue;
                    }
                }
                else if (level == 6)
                {
                    if (lexem.kind == LexemKind.DIVIDE)
                    {
                        count++;
                        list.Add(buffer);
                        buffer = new List <Lexem>();
                        continue;
                    }
                }
                buffer.Add(lexem);
            }

            if (count == 1)
            {
                return(parseCommandPart(buffer, level + 1));
            }
            else
            {
                list.Add(buffer);
                if (level == 0)
                {
                    CommandLogicCompound compound = new CommandLogicCompound(LexemKind.AND);
                    foreach (List <Lexem> sub in list)
                    {
                        compound.addBlock(parseCommandPart(sub, level + 1));
                    }
                    return(compound);
                }
                else if (level == 1)
                {
                    CommandLogicCompound compound = new CommandLogicCompound(LexemKind.OR);
                    foreach (List <Lexem> sub in list)
                    {
                        compound.addBlock(parseCommandPart(sub, level + 1));
                    }
                    return(compound);
                }
                else if (level == 2)
                {
                    if (compareKind == LexemKind.UNKNOWN || count > 2)
                    {
                        return(null);
                    }
                    CommandLogic compound = new CommandLogic(
                        compareKind,
                        parseCommandPart(list[0], level + 1),
                        parseCommandPart(list[1], level + 1)
                        );
                    return(compound);
                }
                else if (level == 3)
                {
                    CommandMath compound = new CommandMath(LexemKind.PLUS);
                    foreach (List <Lexem> sub in list)
                    {
                        compound.addBlock(parseCommandPart(sub, level + 1));
                    }
                    return(compound);
                }
                else if (level == 4)
                {
                    CommandMath compound = new CommandMath(LexemKind.MINUS);
                    foreach (List <Lexem> sub in list)
                    {
                        compound.addBlock(parseCommandPart(sub, level + 1));
                    }
                    return(compound);
                }
                else if (level == 5)
                {
                    CommandMath compound = new CommandMath(LexemKind.MULTIPLY);
                    foreach (List <Lexem> sub in list)
                    {
                        compound.addBlock(parseCommandPart(sub, level + 1));
                    }
                    return(compound);
                }
                else if (level == 6)
                {
                    CommandMath compound = new CommandMath(LexemKind.DIVIDE);
                    foreach (List <Lexem> sub in list)
                    {
                        compound.addBlock(parseCommandPart(sub, level + 1));
                    }
                    return(compound);
                }
            }

            return(null);
        }
Esempio n. 9
0
 public CommandLogic(LexemKind operation, ICommand left, ICommand right)
 {
     this.operation = operation;
     this.left      = left;
     this.right     = right;
 }
Esempio n. 10
0
        private void parse(List <Lexem> list)
        {
            LexemKind kind     = LexemKind.UNKNOWN;
            LexemKind prevKind = LexemKind.UNKNOWN;

            while (offset < sourceLength)
            {
                //пропуск лишних символов (пробел, таб, новая строка, перенос каретки)
                char c = source[offset];
                while (offset < sourceLength && LexemDefinitions.isEmptyCharacter(c))
                {
                    offset++;
                    if (offset >= sourceLength)
                    {
                        break;
                    }
                    c = source[offset];
                }

                if (offset >= sourceLength || LexemDefinitions.isCloseBrace(c))
                {
                    offset++;
                    break;
                }

                /*Match match = COMMENT.Match(source, offset);
                 * if (match.Success) {
                 *  this.offset += match.Length;
                 *  continue;
                 * }*/

                Lexem lexem = parseStatic() ?? parseDynamic();
                if (lexem == null)
                {
                    throw new Exception(string.Format("Неизвестная лексема на позиции {0}: {1}", offset, source.Substring(offset, Math.Min(30, sourceLength - offset)).Replace("<", "&lt;").Replace(">", "&gt;")));
                }

                kind = lexem.kind;
                if (kind == LexemKind.BRACE || kind == LexemKind.BLOCK || kind == LexemKind.INDEX)
                {
                    List <Lexem> childs = new List <Lexem>();
                    parse(childs);
                    lexem.childs = childs;
                }
                else if (kind == LexemKind.NUMBER && prevKind == LexemKind.MINUS)
                {
                    if (list.Count >= 2 && (list[list.Count - 2].kind == LexemKind.ASSIGN || list[list.Count - 2].kind == LexemKind.COMMA))
                    {
                        list.RemoveAt(list.Count - 1);
                    }
                    else
                    {
                        list[list.Count - 1].kind = LexemKind.PLUS;
                    }
                    lexem.value = "-" + lexem.value;
                }

                list.Add(lexem);

                prevKind = kind;
            }
        }
Esempio n. 11
0
 public CommandLogic(Stream stream, SerializationInfo info)
 {
     operation = (LexemKind)stream.ReadByte();
     left      = SerializationHelper.deSerialize(stream, info);
     right     = SerializationHelper.deSerialize(stream, info);
 }
Esempio n. 12
0
 public CommandUnary(ICommand command, LexemKind operation)
 {
     this.command   = command;
     this.operation = operation;
 }
Esempio n. 13
0
 public CommandUnary(Stream stream, SerializationInfo info)
 {
     command   = SerializationHelper.deSerialize(stream, info);
     operation = (LexemKind)stream.ReadByte();
 }
Esempio n. 14
0
 public CommandLogicCompound(LexemKind operation)
 {
     this.operation = operation;
 }
Esempio n. 15
0
 public CommandLogicCompound(Stream stream, SerializationInfo info)
 {
     operation = (LexemKind)stream.ReadByte();
     SerializationHelper.deserializeBlock(stream, info, blocks);
 }
Esempio n. 16
0
 public StaticLexemDefinition(string representation, LexemKind kind)
 {
     this.representation = representation;
     this.kind           = kind;
     this.isKeyword      = false;
 }
Esempio n. 17
0
 public DynamicLexemDefinition(string representation, LexemKind kind, string flags)
 {
     this.representation = new Regex(@"\G" + flags + representation, RegexOptions.Compiled);
     this.kind           = kind;
 }
Esempio n. 18
0
 public CommandMath(LexemKind operation)
 {
     this.operation = operation;
 }