private Node HandleSuperExpression() { var cond = HandleExpression(); if (_tokenizer.Match(TokenType.QuestionMark)) { var whenTrue = HandleExpression(); if (!_tokenizer.Match(TokenType.Colon)) { return(new ErrorNode("Expected ':'.")); } var whenFalse = HandleExpression(); return(new IfNode(cond, whenTrue, whenFalse)); } return(cond); }
/// <summary> /// positive-factor → number | ‘(’ expression ‘)’ /// </summary> private static double ComputePositiveFactor(ITokenizer tokenizer) { if (tokenizer.MatchDouble(out var factor)) { return(factor); } if (!tokenizer.Match(TokenType.OpenParenthesis)) { throw new Exception("Expected number or (."); } factor = ComputeTernaryExpression(tokenizer); if (!tokenizer.Match(TokenType.CloseParenthesis)) { throw new Exception("Expected )."); } return(factor); }
/// <summary> /// expression → term [operator-additive term]* /// </summary> private static double ComputeExpression(ITokenizer tokenizer) { var expression = ComputeTerm(tokenizer); while ((tokenizer.CurrentToken & TokenType.IsAdditiveOperator) != TokenType.None) { if (tokenizer.Match(TokenType.Plus)) { expression += ComputeTerm(tokenizer); } if (tokenizer.Match(TokenType.Minus)) { expression -= ComputeTerm(tokenizer); } } return(expression); }
/// <summary> /// term → factor [operator-multiplicative factor]* /// </summary> private static double ComputeTerm(ITokenizer tokenizer) { var factor = ComputeFactor(tokenizer); while ((tokenizer.CurrentToken & TokenType.IsMultiplicativeOperator) != TokenType.None) { if (tokenizer.Match(TokenType.Multiplicative)) { factor *= ComputeFactor(tokenizer); } if (tokenizer.Match(TokenType.Divide)) { factor /= ComputeFactor(tokenizer); } } return(factor); }
/// <summary> /// ternaryExpression -> expression ? ternaryExpression : ternaryExpression /// </summary> private static double ComputeTernaryExpression(ITokenizer tokenizer) { var ternaryExpression = ComputeExpression(tokenizer); if (!tokenizer.Match(TokenType.QuestionMark)) { return(ternaryExpression); } var truthlyDouble = ComputeTernaryExpression(tokenizer); if (!tokenizer.Match(TokenType.Colon)) { throw new Exception("Expected :."); } var falsyDouble = ComputeTernaryExpression(tokenizer); return(ternaryExpression > 0 ? truthlyDouble : falsyDouble); }
private Node ParseTernaryExpression(ITokenizer tokenizer) { var condition = ParseExpression(tokenizer); if (!tokenizer.Match(TokenType.QuestionMark)) { return(condition); } var truthly = ParseTernaryExpression(tokenizer); if (!tokenizer.Match(TokenType.Colon)) { return(new TernaryNode(condition, truthly, new ErrorNode("Expected :."))); } var falsy = ParseTernaryExpression(tokenizer); return(new TernaryNode(condition, truthly, falsy)); }
private MarkdownParsingResult <INode> ParseEscaped(ITokenizer <IMdToken> tokenizer) { var tokens = tokenizer.Match(token => token.Has(Md.Escaped)); if (tokens.Succeed) { return(tokens.Remainder.SuccessWith <INode>(new EscapedTextNode(tokens.Parsed.Text))); } return(tokenizer.Fail <INode>()); }
private Node ParsePositiveFactor(ITokenizer tokenizer) { if (tokenizer.MatchDouble(out var value)) { return(new ConstantNode(value)); } if (tokenizer.MatchIdentifier(out var id)) { return(new IdentifierNode(id)); } if (!tokenizer.Match(TokenType.OpenParenthesis)) { return(new ErrorNode("Expected number or (.")); } var factor = ParseExpression(tokenizer); if (!tokenizer.Match(TokenType.CloseParenthesis)) { return(new ErrorNode("Expected ).")); } return(factor); }
private MarkdownParsingResult <INode> ParseHeader(ITokenizer <IMdToken> tokenizer) { var header = tokenizer.Match(token => token.Has(Md.Header)); var boundedTokenizer = header.IfSuccess(t => { var bounded = t.UntilNotMatch(token => token.HasAny(Md.NewLine, Md.Break)); return(SkipWhiteSpaces(bounded)); }); var headerContent = boundedTokenizer.IfSuccess(t => ParseNodesUntilMatch(t, ParseFormattedText)); if (headerContent.Succeed) { return(headerContent.Remainder.UnboundTokenizer().SuccessWith <INode>( new HeaderNode(header.Parsed.Text.Length, headerContent.Parsed) )); } return(tokenizer.Fail <INode>()); }
private MarkdownParsingResult <INode> ParseLink(ITokenizer <IMdToken> tokenizer) { var openText = tokenizer.Match(token => token.Has(Md.LinkText, Md.Open)); var text = openText.IfSuccess(ParseTextWithEscaped); var closeText = text.IfSuccess(t => t.Match(token => token.Has(Md.LinkText, Md.Close))); var openLink = closeText .IfSuccess(SkipWhiteSpaces) .IfSuccess(t => t.Match(token => token.Has(Md.LinkReference, Md.Open))); var link = openLink.IfSuccess(ParsePlainText); var closeLink = link.IfSuccess(t => t.Match(token => token.Has(Md.LinkReference, Md.Close))); if (closeLink.Succeed) { var linkText = ((TextNode)link.Parsed).Text; return(closeLink.Remainder.SuccessWith <INode>(new LinkNode(linkText, text.Parsed))); } return(tokenizer.Fail <INode>()); }
FunctionNode IsFunction() { if (!_tokenizer.MatchIdentifier("function")) { return(null); } string name; string returnType; List <string> parameters = new List <string>(); // Si ensuite on a les autres infos et une ouverture de parenthèse if (_tokenizer.IsIdentifier(out returnType) && _tokenizer.IsIdentifier(out name) && _tokenizer.Match(TokenType.OpenPar)) { // On prend tout les params while (!_tokenizer.Match(TokenType.ClosedPar)) { string parameterType; string osef; if (_tokenizer.IsIdentifier(out parameterType) && _tokenizer.IsIdentifier(out osef)) { parameters.Add(parameterType); } else { AddError("PB !"); return(null); } _tokenizer.Match(TokenType.Comma); } if (_tokenizer.Match(TokenType.OpenCurly)) { FunctionNode fct = new FunctionNode(name, returnType, ParseFunctionBody(), parameters); return(fct); } else { AddError("Cannot begin function... :("); } } else { AddError("Error on Function creation..."); } return(null); }
/// <summary> /// factor ==> positive-factor | '-' positive-factor /// </summary> private static double ComputeFactor(ITokenizer tokenizer) => tokenizer.Match(TokenType.Minus) ? -ComputePositiveFactor(tokenizer) : ComputePositiveFactor(tokenizer);
private Node ParseFactor(ITokenizer tokenizer) => tokenizer.Match(TokenType.Minus) ? new UnaryNode(TokenType.Minus, ParsePositiveFactor(tokenizer)) : ParsePositiveFactor(tokenizer);