public decimal GetRatingForSentence(string channel, string sentence) { var rating = 0m; var tokenSentence = new TokenList(sentence); var nextToken = tokenSentence.GetEnumerator(); var hasNextToken = nextToken.MoveNext(); var usedStems = new List <Stem>(); while (hasNextToken) { var stem = StemManager.GetStemForToken(nextToken.Current); if (stem != null && ChannelMemoryManager.Instance.HasStemInChannel(channel, stem) && !usedStems.Contains(stem)) { rating += ChannelMemoryManager.Instance.GetValueForStem(channel, stem); usedStems.Add(stem); } hasNextToken = nextToken.MoveNext(); } if (tokenSentence.Get().Count == 0) { return(rating); } var power = Math.Pow(tokenSentence.Get().Count, 0.5); var multiplier = (decimal)(1 / power); rating = rating * multiplier; return(rating); }
public void TrainTokenList(TokenList tokenList, Token currentToken, List <Token> existingTokens, List <Token> linkedTokens = null) { var tokenListTotal = tokenList.Get().Count; var currentTokenCounter = 0; var nextToken = tokenList.GetEnumerator(); var hasNextToken = nextToken.MoveNext(); while (hasNextToken) { currentTokenCounter++; if (TokenManager.DoesWordTextExist(nextToken.Current, currentToken, out var outIndex)) { currentToken = TokenManager.TrainExistingToken(currentToken, outIndex); if (existingTokens != null && existingTokens.Contains(currentToken)) { existingTokens = null; } } else { if (existingTokens != null && existingTokens.Count > 0 && (existingTokens.Count + currentTokenCounter - 1) == tokenListTotal && existingTokens[0].WordText.Equals(nextToken.Current)) { currentToken = TokenManager.TrainReferenceExistingToken(currentToken, existingTokens[0], outIndex); existingTokens.RemoveAt(0); } else { currentToken = TokenManager.TrainNewToken(currentToken, nextToken.Current, outIndex); } } if (linkedTokens?.Count > 0) { TokenManager.LinkTokensAndRemoveFirstItem(currentToken, linkedTokens); } hasNextToken = nextToken.MoveNext(); } }
/// <summary> /// Парсит конструкцию SWITCH. /// </summary> private static void ParseSwitch(TokenList body) { BaseGenerator generator = CodeManager.GetGenerator(parseMode); for (int index = 0; index < body.Count; index++) { TokenList nextTokens = body.GetRange(index); Token currentToken = body[index]; Token nextToken = body.Get(index + 1); if (currentToken.TypeIs(TokenType.NextLine)) { lineIndex++; continue; } // случай <expression>: if (currentToken.TypeIs(KeywordType.Case) && body[index + 2].TypeIs(TokenType.Colon)) { TokenList caseBody = GetCaseBody(nextTokens, out index, index); generator.AddCaseConstruction(nextToken); Parse(caseBody, out _); } // по_умолчанию: else if (currentToken.TypeIs(KeywordType.Default) && body[index + 1].TypeIs(TokenType.Colon)) { TokenList defaultBody = GetCaseBody(nextTokens, out index, index); generator.AddDefaultCaseConstruction(); Parse(defaultBody, out _); } // завершить; else if (currentToken.TypeIs(KeywordType.Break)) { generator.AddBreak(); } } }
protected override ParsingInfo Parse(TokenList list) { var token = list.Get <TokenType>(); if (token == null) { errorInfo.Add(new ParseErrorInfo() { expected = (typeof(TokenType).Name), got = (list.Current.ToString()), tokenGot = list.Current, }); Error = true; return(null); } if (filter != null && filter(token) == false) { list.MoveToPrevious(); errorInfo.Add(new ParseErrorInfo() { expected = (typeof(TokenType).Name), got = (list.Current.ToString() + ", but filter failed"), tokenGot = list.Current, }); Error = true; return(null); } ParsingInfo info = new ParsingInfo { { name, token } }; return(info); }
/// <summary> /// Парсит тела конструкций, в том числе и новой функции. /// </summary> public static void Parse(TokenList tokens, out int counter, bool isRoot = false) { counter = 0; while (counter < tokens.Count) { BaseGenerator generator = CodeManager.GetGenerator(parseMode); TokenList nextTokens = tokens.GetRange(counter); Token currentToken = tokens[counter]; Token nextToken = tokens.Get(counter + 1); if (currentToken.TypeIs(TokenType.NextLine)) { lineIndex++; counter++; continue; } if (currentToken.TypeIs(TokenType.Id)) { // <variableName> = <expression>; if (nextToken.TypeIs(TokenType.AssignOperator)) { string variableName = currentToken.value; TokenList expression = nextTokens.GetRange(nextTokens.IndexOf("=") + 1, nextTokens.IndexOf(";")); generator.AddVariableAssignment(variableName, expression, isRoot); counter += nextTokens.IndexOf(";") + 1; } // <id>(<expression>); else if (nextToken.TypeIs(TokenType.BeginParenthesis)) { Token name = currentToken; TokenList attributes = GetExpressionInParenthesis(nextTokens, errors: false); if (attributes.Count == 0 && !nextTokens.Get(2).TypeIs(TokenType.EndParenthesis)) { throw new ParseException($"После '(' при вызове функции без параметров ожидалось ')', а не '{nextToken}'", lineIndex); } generator.AddFunctionCall(name, attributes); counter += nextTokens.IndexOf(";") + 1; } else { throw new ParseException($"После '{currentToken}' ожидалось '=' либо '(', а не '{nextToken}'", lineIndex); } } else if (currentToken.TypeIs(TokenType.Keyword)) { // функция <functionName>(<parameters>) { <functionBody> } if (currentToken.TypeIs(KeywordType.Function)) { NewFunction newFunction = CodeManager.NewFunction; string name = nextToken.value; TokenList parameters = GetExpressionInParenthesis(nextTokens, errors: false); TokenList body = GetBody(nextTokens, out counter, counter); if (!nextToken.TypeIs(TokenType.Id)) { throw new ParseException($"После ключевого слова 'функция' ожидалось название объявляемой функции, а не '{nextToken}'", lineIndex); } if (!nextTokens.Get(2).TypeIs(TokenType.BeginParenthesis)) { throw new ParseException($"После названия функции ожидалось '(', а не '{nextToken}'", lineIndex); } if (parameters.Count == 0 && !nextTokens.Get(3).TypeIs(TokenType.EndParenthesis)) { throw new ParseException($"После '(' при объявлении функции без параметров ожидалось ')', а не '{nextToken}'", lineIndex); } parameters.DeleteAll(","); newFunction.AddFunctionHeader(name, parameters); parseMode = ParseMode.FunctionCreation; Parse(body, out _); newFunction.Create(); parseMode = ParseMode.Default; } // если (<expresion>) { <body> } else if (currentToken.TypeIs(KeywordType.If)) { TokenList expression = GetExpressionInParenthesis(nextTokens); TokenList body = GetBody(nextTokens, out counter, counter); if (!nextToken.TypeIs(TokenType.BeginParenthesis)) { throw new ParseException($"После ')' ожидалось '{{', а не {nextToken}", lineIndex); } generator.AddIfConstruction(expression); Parse(body, out _); generator.AddConstructionEnd(); } // иначе { <body> } else if (currentToken.TypeIs(KeywordType.Else)) { TokenList body = GetBody(nextTokens, out counter, counter); generator.AddElseConstruction(); Parse(body, out _); generator.AddConstructionEnd(); } // делать { <body> } пока (<expression>) else if (currentToken.TypeIs(KeywordType.Do)) { TokenList body = GetBody(nextTokens, out counter, counter); generator.AddDoConstruction(); Parse(body, out _); generator.AddConstructionEnd(); nextTokens = tokens.GetRange(counter); currentToken = tokens[counter]; if (currentToken.TypeIs(KeywordType.While)) { TokenList expression = GetExpressionInParenthesis(nextTokens); if (expression.Count == 0) { throw new ParseException($"Конструкция 'пока' без выражения", lineIndex); } generator.AddEndingWhileConstruction(expression); counter += nextTokens.IndexOf(";") + 1; } else { throw new ParseException($"После окончания конструкции 'делать' ожидалось ключевое слово 'пока'", lineIndex); } } // пока (<expression>) { <body> } else if (currentToken.TypeIs(KeywordType.While)) { TokenList expression = GetExpressionInParenthesis(nextTokens); TokenList body = GetBody(nextTokens, out counter, counter); generator.AddWhileConstruction(expression); Parse(body, out _); generator.AddConstructionEnd(); } // пробовать { <tryBody> } отловить [(<errorValue>)] { <catchBody> } else if (currentToken.TypeIs(KeywordType.Try)) { TokenList tryBody = GetBody(nextTokens, out counter, counter); generator.AddTryConstruction(); Parse(tryBody, out _); generator.AddConstructionEnd(); nextTokens = tokens.GetRange(counter); currentToken = tokens[counter]; if (currentToken.TypeIs(KeywordType.Catch)) { TokenList expression = GetExpressionInParenthesis(nextTokens, errors: false); TokenList catchBody = GetBody(nextTokens, out counter, counter); if (expression.Count == 1 && expression[0].TypeIs(TokenType.Id)) { generator.AddCatchConstruction(expression[0]); } else { generator.AddCatchConstruction(); } Parse(catchBody, out _); generator.AddConstructionEnd(); } } // определить (<value>) { <body> } else if (currentToken.TypeIs(KeywordType.Switch)) { TokenList expression = GetExpressionInParenthesis(nextTokens); TokenList body = GetBody(nextTokens, out counter, counter); if (expression.Count == 1 && expression[0].TypeIs(TokenType.Id)) { generator.AddSwitchConstruction(expression[0]); ParseSwitch(body); generator.AddConstructionEnd(); } } // использовать ... else if (currentToken.TypeIs(KeywordType.Use)) { // ссылки "<path>" if (nextToken.TypeIs(KeywordType.Links) && nextTokens.Get(2).TypeIs(TokenType.String) && Path.GetExtension(nextTokens[2].value) == GlobalParams.linksExtention) { CodeManager.UpdateNamesMap(nextTokens[2].value); } // <id> else if (nextToken.TypeIs(TokenType.Id)) { Compilator.AddUsing(nextToken.ToString()); Compilator.AddClassRef(nextToken.ToString()); } counter += nextTokens.IndexOf(";") + 1; } // импорт ... else if (currentToken.TypeIs(KeywordType.Import)) { if (nextToken.TypeIs(TokenType.String)) { string path = nextToken.value; if (File.Exists(path)) { string extention = Path.GetExtension(path); if (extention == GlobalParams.codeExtention) { // ...... } else { Compilator.AddRef(path); } } } counter += nextTokens.IndexOf(";") + 1; } else { throw new ParseException($"На первой позиции не ожидалось ключевое слово {currentToken}", lineIndex); } } else { throw new ParseException($"Не удалось распознать слово '{currentToken}'", lineIndex); } } }