/// <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); }
/// <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())); }
protected Lexem(LexemKind kind) { Kind = kind; }
private bool Check(LexemKind lexem, int lexemId) { var lex = Lexems[lexemId]; if (lex.Kind != lexem) return false; return true; }
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; }
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; }
/// <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); }
public CommandLogic(LexemKind operation, ICommand left, ICommand right) { this.operation = operation; this.left = left; this.right = right; }
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("<", "<").Replace(">", ">"))); } 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; } }
public CommandLogic(Stream stream, SerializationInfo info) { operation = (LexemKind)stream.ReadByte(); left = SerializationHelper.deSerialize(stream, info); right = SerializationHelper.deSerialize(stream, info); }
public CommandUnary(ICommand command, LexemKind operation) { this.command = command; this.operation = operation; }
public CommandUnary(Stream stream, SerializationInfo info) { command = SerializationHelper.deSerialize(stream, info); operation = (LexemKind)stream.ReadByte(); }
public CommandLogicCompound(LexemKind operation) { this.operation = operation; }
public CommandLogicCompound(Stream stream, SerializationInfo info) { operation = (LexemKind)stream.ReadByte(); SerializationHelper.deserializeBlock(stream, info, blocks); }
public StaticLexemDefinition(string representation, LexemKind kind) { this.representation = representation; this.kind = kind; this.isKeyword = false; }
public DynamicLexemDefinition(string representation, LexemKind kind, string flags) { this.representation = new Regex(@"\G" + flags + representation, RegexOptions.Compiled); this.kind = kind; }
public CommandMath(LexemKind operation) { this.operation = operation; }