private IParseResult ParseBinaryExp <T>(Parser parser, IEnumerable <OperatorType> availableOperators) where T : BinaryExp { var left = parser(); if (!left.IsSuccess || left.IsNullStat()) { return(left); } OperatorToken op = null; // ReSharper disable once PossibleMultipleEnumeration while (Accept(availableOperators, ref op)) { var right = parser(); if (!right.IsSuccess) { return(right); } if (right.IsNullStat()) { return(ExpectedExpressionFailure()); } var constructor = typeof(T).GetConstructor(new[] { typeof(OperatorToken), typeof(ExpNode), typeof(ExpNode), typeof(Position) }); if (constructor == null) { throw new ArgumentException($"{typeof(T)} not suitable for creating BinaryExp"); } var leftExpNode = left.ResultNode as ExpNode; var @object = constructor.Invoke(new object[] { op, leftExpNode, right.ResultNode as ExpNode, leftExpNode.StartNodePosition }); left = new SuccessParseResult(@object as Node); } return(left); }
/* * direct_declarator : id | '(' declarator ')' | direct_declarator '[' conditional_exp ']' | direct_declarator '[' ']' | direct_declarator '(' param_list ')' | direct_declarator '(' id_list ')' | direct_declarator '(' ')' | ; */ private IParseResult ParseDirectDeclarator() { IParseResult left; var id = ParseId(); if (!id.IsNullStat()) { left = id; } else if (Accept(OperatorType.LRBRACKET)) { var declarator = ParseDeclarator(); if (!declarator.IsSuccess) { return(declarator); } if (declarator.IsNullStat()) { return(new FailedParseResult("expected declarator", _currentToken)); } Expect(OperatorType.RRBRACKET); left = declarator; } else { return(new SuccessParseResult(new NullStat())); } OperatorToken op = null; while (Accept(new [] { OperatorType.LSBRACKET, OperatorType.LRBRACKET }, ref op)) { if (op.Type == OperatorType.LSBRACKET) { if (Accept(OperatorType.RSBRACKET)) { left = new SuccessParseResult(new ArrayDecl(left.ResultNode, new EmptyExp())); continue; } var conditionalExp = ParseConditionalExp(); if (!conditionalExp.IsSuccess) { return(conditionalExp); } if (conditionalExp.IsNullStat()) { return(ExpectedExpressionFailure()); } Expect(OperatorType.RSBRACKET); left = new SuccessParseResult(new ArrayDecl(left.ResultNode, conditionalExp.ResultNode)); continue; } if (op.Type == OperatorType.LRBRACKET) { if (Accept(OperatorType.RRBRACKET)) { left = new SuccessParseResult(new FuncDecl(left.ResultNode, new EmptyExp())); continue; } var paramList = ParseParamList(); if (!paramList.IsSuccess) { return(paramList); } if (!paramList.IsNullStat()) { Expect(OperatorType.RRBRACKET); left = new SuccessParseResult(new FuncDecl(left.ResultNode, paramList.ResultNode)); continue; } var idList = ParseIdList(); if (!idList.IsSuccess) { return(idList); } if (idList.IsNullStat()) { return(new FailedParseResult("expected parameter list", _currentToken)); } Expect(OperatorType.RRBRACKET); left = new SuccessParseResult(new FuncDecl(left.ResultNode, idList.ResultNode)); continue; } break; } return(left); }
/* * postfix_exp : primary_exp | postfix_exp '[' exp ']' | postfix_exp '(' argument_exp_list ')' | postfix_exp '(' ')' | postfix_exp '.' id | postfix_exp '->' id | postfix_exp '++' | postfix_exp '--' */ private IParseResult ParsePostfixExp() { var result = ParsePrimaryExp(); if (!result.IsSuccess || result.IsNullStat()) { return(result); } while (true) { var resultExpNode = result.ResultNode as ExpNode; if (Accept(OperatorType.LSBRACKET)) { var exp = ParseExp(); if (!exp.IsSuccess) { return(exp); } if (exp.IsNullStat()) { return(ExpectedExpressionFailure()); } Expect(OperatorType.RSBRACKET); result = new SuccessParseResult(new AccessingArrayElement(resultExpNode, exp.ResultNode as ExpNode, resultExpNode.StartNodePosition)); continue; } if (Accept(OperatorType.LRBRACKET)) { if (Accept(OperatorType.RRBRACKET)) { result = new SuccessParseResult(new FuncCall(resultExpNode, new NullStat(), resultExpNode.StartNodePosition)); continue; } var exp = ParseList <ExpList>(ParseAssignmentExp, OperatorType.COMMA); if (!exp.IsSuccess) { return(exp); } Expect(OperatorType.RRBRACKET); result = new SuccessParseResult(new FuncCall(resultExpNode, exp.ResultNode, resultExpNode.StartNodePosition)); continue; } OperatorToken op = null; if (Accept(new [] { OperatorType.DOT, OperatorType.RARROW }, ref op)) { var id = ParseId(); if (id.IsNullStat()) { return(new FailedParseResult("expected identifier", _currentToken)); } result = new SuccessParseResult( new MemberCall(resultExpNode, id.ResultNode as ExpNode, (op.Type == OperatorType.DOT ? MemberCall.CallType.VALUE : MemberCall.CallType.POINTER), resultExpNode.StartNodePosition)); continue; } if (Accept(new [] { OperatorType.INC, OperatorType.DEC }, ref op)) { result = new SuccessParseResult(new PostfixIncDec(resultExpNode, (op.Type == OperatorType.INC ? PostfixIncDec.OpType.INC : PostfixIncDec.OpType.DEC), resultExpNode.StartNodePosition)); continue; } break; } return(result); }
protected internal virtual Task SetResultSafe(ModelBindingContext context, string parameterName, SuccessParseResult result, JsonSerializer serializer) { try { log.LogTrace($"{nameof(SetResultSafe)}, parameterName {parameterName}: [{result}]"); SetDeserializedResult(context, result.Value, serializer); } catch (Exception e) { log.LogWarning(e, $"{nameof(SetResultSafe)}, parameterName {parameterName} failed result was [{result}]"); context.ModelState.AddModelError(parameterName, $"{result}. {e.GetType().Name}: {e.Message}"); } return(Task.CompletedTask); }