Диплом: Автоматизация и обеспечение информационной безопасности приема заявок на ремонт и модернизацию ПК в ООО "Гео-СВЕТ"

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам
112
return ParsePrimary();
}
Expression expr = ParseUnary();
if (op.id == TokenId.Minus) {
CheckAndPromoteOperand(typeof(INegationSignatures), op.text, ref expr, op.pos);
expr = Expression.Negate(expr);
}
else {
CheckAndPromoteOperand(typeof(INotSignatures), op.text, ref expr, op.pos);
expr = Expression.Not(expr);
}
return expr;
}
return ParsePrimary();
}
Expression ParsePrimary() {
Expression expr = ParsePrimaryStart();
while (true) {
if (token.id == TokenId.Dot) {
NextToken();
expr = ParseMemberAccess(null, expr);
}
else if (token.id == TokenId.OpenBracket) {
expr = ParseElementAccess(expr);
}
else {
break;
}
}
return expr;
}
Expression ParsePrimaryStart() {
switch (token.id) {
case TokenId.Identifier:
return ParseIdentifier();
case TokenId.StringLiteral:
return ParseStringLiteral();
case TokenId.IntegerLiteral:
return ParseIntegerLiteral();
case TokenId.RealLiteral:
return ParseRealLiteral();
case TokenId.OpenParen:
return ParseParenExpression();
default:
throw ParseError(Res.ExpressionExpected);
}
}
Expression ParseStringLiteral() {
ValidateToken(TokenId.StringLiteral);
char quote = token.text[0];
string s = token.text.Substring(1, token.text.Length - 2);
int start = 0;
while (true) {
int i = s.IndexOf(quote, start);
113
if (i < 0) break;
s = s.Remove(i, 1);
start = i + 1;
}
if (quote == '\'') {
if (s.Length != 1)
throw ParseError(Res.InvalidCharacterLiteral);
NextToken();
return CreateLiteral(s[0], s);
}
NextToken();
return CreateLiteral(s, s);
}
Expression ParseIntegerLiteral() {
ValidateToken(TokenId.IntegerLiteral);
string text = token.text;
if (text[0] != '-') {
ulong value;
if (!UInt64.TryParse(text, out value))
throw ParseError(Res.InvalidIntegerLiteral, text);
NextToken();
if (value <= (ulong)Int32.MaxValue) return CreateLiteral((int)value, text);
if (value <= (ulong)UInt32.MaxValue) return CreateLiteral((uint)value, text);
if (value <= (ulong)Int64.MaxValue) return CreateLiteral((long)value, text);
return CreateLiteral(value, text);
}
else {
long value;
if (!Int64.TryParse(text, out value))
throw ParseError(Res.InvalidIntegerLiteral, text);
NextToken();
if (value >= Int32.MinValue && value <= Int32.MaxValue)
return CreateLiteral((int)value, text);
return CreateLiteral(value, text);
}
}
Expression ParseRealLiteral() {
ValidateToken(TokenId.RealLiteral);
string text = token.text;
object value = null;
char last = text[text.Length - 1];
if (last == 'F' || last == 'f') {
float f;
if (Single.TryParse(text.Substring(0, text.Length - 1), out f)) value = f;
}
else {
double d;
if (Double.TryParse(text, out d)) value = d;
}
if (value == null) throw ParseError(Res.InvalidRealLiteral, text);
NextToken();
return CreateLiteral(value, text);
}
Expression CreateLiteral(object value, string text) {
114
ConstantExpression expr = Expression.Constant(value);
literals.Add(expr, text);
return expr;
}
Expression ParseParenExpression() {
ValidateToken(TokenId.OpenParen, Res.OpenParenExpected);
NextToken();
Expression e = ParseExpression();
ValidateToken(TokenId.CloseParen, Res.CloseParenOrOperatorExpected);
NextToken();
return e;
}
Expression ParseIdentifier() {
ValidateToken(TokenId.Identifier);
object value;
if (keywords.TryGetValue(token.text, out value)) {
if (value is Type) return ParseTypeAccess((Type)value);
if (value == (object)keywordIt) return ParseIt();
if (value == (object)keywordIif) return ParseIif();
if (value == (object)keywordNew) return ParseNew();
NextToken();
return (Expression)value;
}
if (symbols.TryGetValue(token.text, out value) ||
externals != null && externals.TryGetValue(token.text, out value)) {
Expression expr = value as Expression;
if (expr == null) {
expr = Expression.Constant(value);
}
else {
LambdaExpression lambda = expr as LambdaExpression;
if (lambda != null) return ParseLambdaInvocation(lambda);
}
NextToken();
return expr;
}
if (it != null) return ParseMemberAccess(null, it);
throw ParseError(Res.UnknownIdentifier, token.text);
}
Expression ParseIt() {
if (it == null)
throw ParseError(Res.NoItInScope);
NextToken();
return it;
}
Expression ParseIif() {
int errorPos = token.pos;
NextToken();
Expression[] args = ParseArgumentList();
if (args.Length != 3)
throw ParseError(errorPos, Res.IifRequiresThreeArgs);
return GenerateConditional(args[0], args[1], args[2], errorPos);
}
115
Expression GenerateConditional(Expression test, Expression expr1, Expression expr2, int
errorPos) {
if (test.Type != typeof(bool))
throw ParseError(errorPos, Res.FirstExprMustBeBool);
if (expr1.Type != expr2.Type) {
Expression expr1as2 = expr2 != nullLiteral ? PromoteExpression(expr1, expr2.Type, true) :
null;
Expression expr2as1 = expr1 != nullLiteral ? PromoteExpression(expr2, expr1.Type, true) :
null;
if (expr1as2 != null && expr2as1 == null) {
expr1 = expr1as2;
}
else if (expr2as1 != null && expr1as2 == null) {
expr2 = expr2as1;
}
else {
string type1 = expr1 != nullLiteral ? expr1.Type.Name : "null";
string type2 = expr2 != nullLiteral ? expr2.Type.Name : "null";
if (expr1as2 != null && expr2as1 != null)
throw ParseError(errorPos, Res.BothTypesConvertToOther, type1, type2);
throw ParseError(errorPos, Res.NeitherTypeConvertsToOther, type1, type2);
}
}
return Expression.Condition(test, expr1, expr2);
}
Expression ParseNew() {
NextToken();
ValidateToken(TokenId.OpenParen, Res.OpenParenExpected);
NextToken();
List<DynamicProperty> properties = new List<DynamicProperty>();
List<Expression> expressions = new List<Expression>();
while (true) {
int exprPos = token.pos;
Expression expr = ParseExpression();
string propName;
if (TokenIdentifierIs("as")) {
NextToken();
propName = GetIdentifier();
NextToken();
}
else {
MemberExpression me = expr as MemberExpression;
if (me == null) throw ParseError(exprPos, Res.MissingAsClause);
propName = me.Member.Name;
}
expressions.Add(expr);
properties.Add(new DynamicProperty(propName, expr.Type));
if (token.id != TokenId.Comma) break;
NextToken();
}
ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected);
NextToken();
Type type = DynamicExpression.CreateClass(properties);
MemberBinding[] bindings = new MemberBinding[properties.Count];
for (int i = 0; i < bindings.Length; i++)
116
bindings[i] = Expression.Bind(type.GetProperty(properties[i].Name), expressions[i]);
return Expression.MemberInit(Expression.New(type), bindings);
}
Expression ParseLambdaInvocation(LambdaExpression lambda) {
int errorPos = token.pos;
NextToken();
Expression[] args = ParseArgumentList();
MethodBase method;
if (FindMethod(lambda.Type, "Invoke", false, args, out method) != 1)
throw ParseError(errorPos, Res.ArgsIncompatibleWithLambda);
return Expression.Invoke(lambda, args);
}
Expression ParseTypeAccess(Type type) {
int errorPos = token.pos;
NextToken();
if (token.id == TokenId.Question) {
if (!type.IsValueType || IsNullableType(type))
throw ParseError(errorPos, Res.TypeHasNoNullableForm, GetTypeName(type));
type = typeof(Nullable<>).MakeGenericType(type);
NextToken();
}
if (token.id == TokenId.OpenParen) {
Expression[] args = ParseArgumentList();
MethodBase method;
switch (FindBestMethod(type.GetConstructors(), args, out method)) {
case 0:
if (args.Length == 1)
return GenerateConversion(args[0], type, errorPos);
throw ParseError(errorPos, Res.NoMatchingConstructor, GetTypeName(type));
case 1:
return Expression.New((ConstructorInfo)method, args);
default:
throw ParseError(errorPos, Res.AmbiguousConstructorInvocation,
GetTypeName(type));
}
}
ValidateToken(TokenId.Dot, Res.DotOrOpenParenExpected);
NextToken();
return ParseMemberAccess(type, null);
}
Expression GenerateConversion(Expression expr, Type type, int errorPos) {
Type exprType = expr.Type;
if (exprType == type) return expr;
if (exprType.IsValueType && type.IsValueType) {
if ((IsNullableType(exprType) || IsNullableType(type)) &&
GetNonNullableType(exprType) == GetNonNullableType(type))
return Expression.Convert(expr, type);
if ((IsNumericType(exprType) || IsEnumType(exprType)) &&
(IsNumericType(type)) || IsEnumType(type))
return Expression.ConvertChecked(expr, type);
}
if (exprType.IsAssignableFrom(type) || type.IsAssignableFrom(exprType) ||
exprType.IsInterface || type.IsInterface)
return Expression.Convert(expr, type);
117
throw ParseError(errorPos, Res.CannotConvertValue,
GetTypeName(exprType), GetTypeName(type));
}
Expression ParseMemberAccess(Type type, Expression instance) {
if (instance != null) type = instance.Type;
int errorPos = token.pos;
string id = GetIdentifier();
NextToken();
if (token.id == TokenId.OpenParen) {
if (instance != null && type != typeof(string)) {
Type enumerableType = FindGenericType(typeof(IEnumerable<>), type);
if (enumerableType != null) {
Type elementType = enumerableType.GetGenericArguments()[0];
return ParseAggregate(instance, elementType, id, errorPos);
}
}
Expression[] args = ParseArgumentList();
MethodBase mb;
switch (FindMethod(type, id, instance == null, args, out mb)) {
case 0:
throw ParseError(errorPos, Res.NoApplicableMethod,
id, GetTypeName(type));
case 1:
MethodInfo method = (MethodInfo)mb;
if (!IsPredefinedType(method.DeclaringType))
throw ParseError(errorPos, Res.MethodsAreInaccessible,
GetTypeName(method.DeclaringType));
if (method.ReturnType == typeof(void))
throw ParseError(errorPos, Res.MethodIsVoid,
id, GetTypeName(method.DeclaringType));
return Expression.Call(instance, (MethodInfo)method, args);
default:
throw ParseError(errorPos, Res.AmbiguousMethodInvocation,
id, GetTypeName(type));
}
}
else {
MemberInfo member = FindPropertyOrField(type, id, instance == null);
if (member == null)
throw ParseError(errorPos, Res.UnknownPropertyOrField,
id, GetTypeName(type));
return member is PropertyInfo ?
Expression.Property(instance, (PropertyInfo)member) :
Expression.Field(instance, (FieldInfo)member);
}
}
static Type FindGenericType(Type generic, Type type) {
while (type != null && type != typeof(object)) {
if (type.IsGenericType && type.GetGenericTypeDefinition() == generic) return type;
if (generic.IsInterface) {
foreach (Type intfType in type.GetInterfaces()) {
Type found = FindGenericType(generic, intfType);
if (found != null) return found;
}
}
118
type = type.BaseType;
}
return null;
}
Expression ParseAggregate(Expression instance, Type elementType, string methodName, int
errorPos) {
ParameterExpression outerIt = it;
ParameterExpression innerIt = Expression.Parameter(elementType, "");
it = innerIt;
Expression[] args = ParseArgumentList();
it = outerIt;
MethodBase signature;
if (FindMethod(typeof(IEnumerableSignatures), methodName, false, args, out signature) != 1)
throw ParseError(errorPos, Res.NoApplicableAggregate, methodName);
Type[] typeArgs;
if (signature.Name == "Min" || signature.Name == "Max") {
typeArgs = new Type[] { elementType, args[0].Type };
}
else {
typeArgs = new Type[] { elementType };
}
if (args.Length == 0) {
args = new Expression[] { instance };
}
else {
args = new Expression[] { instance, Expression.Lambda(args[0], innerIt) };
}
return Expression.Call(typeof(Enumerable), signature.Name, typeArgs, args);
}
Expression[] ParseArgumentList() {
ValidateToken(TokenId.OpenParen, Res.OpenParenExpected);
NextToken();
Expression[] args = token.id != TokenId.CloseParen ? ParseArguments() : new Expression[0];
ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected);
NextToken();
return args;
}
Expression[] ParseArguments() {
List<Expression> argList = new List<Expression>();
while (true) {
argList.Add(ParseExpression());
if (token.id != TokenId.Comma) break;
NextToken();
}
return argList.ToArray();
}
Expression ParseElementAccess(Expression expr) {
int errorPos = token.pos;
ValidateToken(TokenId.OpenBracket, Res.OpenParenExpected);
NextToken();
Expression[] args = ParseArguments();
ValidateToken(TokenId.CloseBracket, Res.CloseBracketOrCommaExpected);
NextToken();
119
if (expr.Type.IsArray) {
if (expr.Type.GetArrayRank() != 1 || args.Length != 1)
throw ParseError(errorPos, Res.CannotIndexMultiDimArray);
Expression index = PromoteExpression(args[0], typeof(int), true);
if (index == null)
throw ParseError(errorPos, Res.InvalidIndex);
return Expression.ArrayIndex(expr, index);
}
else {
MethodBase mb;
switch (FindIndexer(expr.Type, args, out mb)) {
case 0:
throw ParseError(errorPos, Res.NoApplicableIndexer,
GetTypeName(expr.Type));
case 1:
return Expression.Call(expr, (MethodInfo)mb, args);
default:
throw ParseError(errorPos, Res.AmbiguousIndexerInvocation,
GetTypeName(expr.Type));
}
}
}
static bool IsPredefinedType(Type type) {
foreach (Type t in predefinedTypes) if (t == type) return true;
return false;
}
static bool IsNullableType(Type type) {
return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
}
static Type GetNonNullableType(Type type) {
return IsNullableType(type) ? type.GetGenericArguments()[0] : type;
}
static string GetTypeName(Type type) {
Type baseType = GetNonNullableType(type);
string s = baseType.Name;
if (type != baseType) s += '?';
return s;
}
static bool IsNumericType(Type type) {
return GetNumericTypeKind(type) != 0;
}
static bool IsSignedIntegralType(Type type) {
return GetNumericTypeKind(type) == 2;
}
static bool IsUnsignedIntegralType(Type type) {
return GetNumericTypeKind(type) == 3;
}
static int GetNumericTypeKind(Type type) {
type = GetNonNullableType(type);
120
if (type.IsEnum) return 0;
switch (Type.GetTypeCode(type)) {
case TypeCode.Char:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return 1;
case TypeCode.SByte:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
return 2;
case TypeCode.Byte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
return 3;
default:
return 0;
}
}
static bool IsEnumType(Type type) {
return GetNonNullableType(type).IsEnum;
}
void CheckAndPromoteOperand(Type signatures, string opName, ref Expression expr, int
errorPos) {
Expression[] args = new Expression[] { expr };
MethodBase method;
if (FindMethod(signatures, "F", false, args, out method) != 1)
throw ParseError(errorPos, Res.IncompatibleOperand,
opName, GetTypeName(args[0].Type));
expr = args[0];
}
void CheckAndPromoteOperands(Type signatures, string opName, ref Expression left, ref
Expression right, int errorPos) {
Expression[] args = new Expression[] { left, right };
MethodBase method;
if (FindMethod(signatures, "F", false, args, out method) != 1)
throw IncompatibleOperandsError(opName, left, right, errorPos);
left = args[0];
right = args[1];
}
Exception IncompatibleOperandsError(string opName, Expression left, Expression right, int pos)
{
return ParseError(pos, Res.IncompatibleOperands,
opName, GetTypeName(left.Type), GetTypeName(right.Type));
}
MemberInfo FindPropertyOrField(Type type, string memberName, bool staticAccess) {
BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly |
(staticAccess ? BindingFlags.Static : BindingFlags.Instance);
foreach (Type t in SelfAndBaseTypes(type)) {
MemberInfo[] members = t.FindMembers(MemberTypes.Property | MemberTypes.Field,
121
flags, Type.FilterNameIgnoreCase, memberName);
if (members.Length != 0) return members[0];
}
return null;
}
int FindMethod(Type type, string methodName, bool staticAccess, Expression[] args, out
MethodBase method) {
BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly |
(staticAccess ? BindingFlags.Static : BindingFlags.Instance);
foreach (Type t in SelfAndBaseTypes(type)) {
MemberInfo[] members = t.FindMembers(MemberTypes.Method,
flags, Type.FilterNameIgnoreCase, methodName);
int count = FindBestMethod(members.Cast<MethodBase>(), args, out method);
if (count != 0) return count;
}
method = null;
return 0;
}
int FindIndexer(Type type, Expression[] args, out MethodBase method) {
foreach (Type t in SelfAndBaseTypes(type)) {
MemberInfo[] members = t.GetDefaultMembers();
if (members.Length != 0) {
IEnumerable<MethodBase> methods = members.
OfType<PropertyInfo>().
Select(p => (MethodBase)p.GetGetMethod()).
Where(m => m != null);
int count = FindBestMethod(methods, args, out method);
if (count != 0) return count;
}
}
method = null;
return 0;
}
static IEnumerable<Type> SelfAndBaseTypes(Type type) {
if (type.IsInterface) {
List<Type> types = new List<Type>();
AddInterface(types, type);
return types;
}
return SelfAndBaseClasses(type);
}
static IEnumerable<Type> SelfAndBaseClasses(Type type) {
while (type != null) {
yield return type;
type = type.BaseType;
}
}
static void AddInterface(List<Type> types, Type type) {
if (!types.Contains(type)) {
types.Add(type);
foreach (Type t in type.GetInterfaces()) AddInterface(types, t);
}

Смотрите также:

"Автоматизация обработки заявок ООО "Проектно-Строительная Компания"
"Автоматизация процесса аттестации персонала для ООО "Нэт Бай Нэт Холдинг"
"Анализ интернет-активности конкурентов ( на примере конкурентов "Газпром нефть")
"Бухгалтерский учёт и аудит расчётов с подотчётними лицами в организации на примере ООО "ЛОЦ 10""
«Психологическое сопровождение персонала в организации на примере ООО «Крокус»
Cовершенствование деловой оценки персонала в организации (на примере ООО "Даймонд кейтеринг развитие")
IPO - инструмент финансирования деятельности организации. На примере ПАО «Нефтяная компания «Лукойл»
PR как средство продвижения организации (на примере ПАО "Тамбовский завод "Комсомолец им. Н.С. Артемова")
PR-коммуникации в сфере общественного питания (на примере кафе-кондитерской «Cream Cheese»)
SMM как средство повышения эффективности работы учреждений социокультурной сферы (на примере Малого театра)