public bool Parse(TokensReader expression, bool expression_end) { body = null; haveIf = false; if (expression.tokens.Pop() == TokenType.ELSE) { TokensReader backup = new TokensReader(); backup.Add(expression); try { if (ift.Parse(expression, expression_end)) { haveIf = true; return(true); } } finally { } if (expression_end) { body = backup; } return(true); } else { return(false); } }
public bool Parse(TokensReader expression, bool expression_end) { field = null; local = null; valuetype = null; if (expression.tokens.Pop() == TokenType.LITERAL && expression_end) { expression.tokens.Insert(0, TokenType.LITERAL); TokensReader backup = new TokensReader(); backup.Add(expression); local = PartTemplate.ParseLocal(ref expression); if (local == null) // is field { expression = backup; field = PartTemplate.ParseField(ref expression); } if (expression.tokens.Pop() == TokenType.OPERATOR && expression.operators.Pop() == OperatorType.ASSIGN) { valuetype = PartTemplate.ParseValue(ref expression); if (expression.tokens.Count == 0) { return(true); } else { return(false); } } else { return(false); } } else { return(false); } }
/// <summary> /// Parse getted expression /// </summary> public void ParseExpression(TokensReader expr) { bool error = false; int trypos = -1; try { if (expr.tokens.IsEmpty()) { return; } reparse: TokensTemplate template = strongTemplates[expr.tokens[0]]; try { if (template.Parse(expr, exprend)) { List <TokensError> errs = template.Run(); if (!errs.IsEmpty()) { errors.AddRange(errs); error = true; } } else { error = true; } } catch { error = true; } if (error) { if (!tryTokens.IsEmpty()) { LaterCalls.RemoveLast(); if (trypos < 0) { if (tryPositions.IsEmpty()) // TODO: need to change text of error { errors.Add(new InvalidTokensTemplateError(line, "tryPositions is empty")); tryTokens.Clear(); // сделаем это для того, чтобы эта ошибка не повторялась return; // беспричинно и не было исключений (переведите на английский пж) } else { trypos = tryPositions.Pop(); } } expr.tokens.RemoveAt(trypos); if (count == 0) { count = tryCounts.Pop(); } if (count > 0) { count--; expr.tokens.Insert(trypos, tryTokens.Pop()); goto reparse; } } else { errors.Add(new InvalidTokensTemplateError(line, $"Invalid template of token {expression.tokens[0]}")); } } } catch (KeyNotFoundException) { reparse: foreach (TokensTemplate template in flexTemplates) { TokensReader backup = new TokensReader(); backup.Add(expr); try { if (template.Parse(expr, exprend)) { errors.AddRange(template.Run()); return; } else { expr = backup; } } catch { expr = backup; } } if (!tryTokens.IsEmpty()) { LaterCalls.RemoveLast(); if (trypos < 0) { if (tryPositions.IsEmpty()) // TODO: need to change text of error { errors.Add(new InvalidTokensTemplateError(line, "tryPositions is empty")); tryTokens.Clear(); // сделаем это для того, чтобы эта ошибка не повторялась return; // беспричинно и не было исключений (переведите на английский пж) } else { trypos = tryPositions.Pop(); } } expr.tokens.RemoveAt(trypos); if (count == 0) { count = tryCounts.Pop(); } if (count > 0) { count--; expr.tokens.Insert(trypos, tryTokens.Pop()); goto reparse; } } else { errors.Add(new InvalidTokensTemplateError(line, $"Unknown tokens template {string.Join(" ", expr.tokens)}")); } } finally { if (isFuncBody && needLaterCall) { LaterCalls.Call(); } needLaterCall = true; tryTokens.Clear(); } }
public static Type ParseValue(ref TokensReader expression) { Type type = null; TokenType token = expression.tokens.Pop(); if (token == TokenType.VALUE) { byte valtype = expression.byte_values.Pop(); if (valtype == 0) { type = typeof(object); } else if (valtype == 1) { type = typeof(int); } else if (valtype == 2) { type = typeof(string); } else if (valtype == 3) { type = typeof(sbyte); } else if (valtype == 4) { type = typeof(bool); } else if (valtype == 5) { type = typeof(char); } else if (valtype == 6) { type = typeof(float); } else if (valtype == 7) { type = typeof(short); } else if (valtype == 8) { type = typeof(long); } else if (valtype == 9) { type = typeof(double); } LaterCalls.LoadObject(expression.values.Pop()); } else if (token == TokenType.LITERAL) // is method { expression.tokens.Insert(0, TokenType.LITERAL); TokensReader backup = new TokensReader(); backup.Add(expression); MethodInfo method = ParseCallMethod(ref expression); if (method == null) // is local { expression = backup; LocalBuilder local = ParseLocal(ref expression); if (local != null) { LaterCalls.LoadLocal(local); type = local.LocalType; } else // is field { expression = backup; FieldInfo value = ParseField(ref expression); LaterCalls.LoadField(value); type = value.FieldType; } } else { type = method.ReturnType; } } else if (token == TokenType.NEW) { type = ParseNewObject(ref expression); } else if (token == TokenType.STATEMENT) { if (expression.bool_values.Pop()) { type = ParseSmallStatement(ref expression); } else { if (lvlStatement == 0) { errors.Add(new InvalidTokenError(line, $"There are wrong 'closing statement' token")); } else { lvlStatement--; } } } else if (token == TokenType.OPERATOR) { OperatorType op = expression.operators.Pop(); } if (!expression.tokens.IsEmpty() && expression.tokens[0] == TokenType.OPERATOR) { expression.tokens.RemoveAt(0); OperatorType op = expression.operators.Pop(); if (type != null) { if (type == ParseValue(ref expression)) { LaterCalls.LoadOperator(type, op); } else { errors.Add(new InvalidTypeError( line, $"Type {type} before operator {op} not equals type of value after operator")); } } switch (op) { case OperatorType.EQ: case OperatorType.NOTEQ: case OperatorType.NOT: case OperatorType.AND: case OperatorType.OR: case OperatorType.GT: case OperatorType.LT: case OperatorType.GORE: case OperatorType.LORE: case OperatorType.IN: type = typeof(bool); break; case OperatorType.RANGE: break; case OperatorType.POW: type = typeof(float); break; } } return(type); }