using System; using System.Collections.Generic; using System.Text; namespace Language.Lua { public enum Associativity { NonAssociative, LeftAssociative, RightAssociative } public class OperTable { static Dictionary precedence = new Dictionary(); static Associativity[] associativity; static OperTable() { List operators = new List(); operators.Add(new string[] { "or" }); operators.Add(new string[] { "and" }); operators.Add(new string[] { "==", "~=" }); operators.Add(new string[] { ">", ">=", "<", "<=" }); operators.Add(new string[] { ".." }); operators.Add(new string[] { "+", "-" }); operators.Add(new string[] { "*", "/", "%" }); operators.Add(new string[] { "#", "not" }); operators.Add(new string[] { "^" }); for (int index = 0; index < operators.Count; index++) { foreach (string oper in operators[index]) { precedence.Add(oper, index); } } associativity = new Associativity[operators.Count]; associativity[0] = Associativity.LeftAssociative; associativity[1] = Associativity.LeftAssociative; associativity[2] = Associativity.NonAssociative; associativity[3] = Associativity.LeftAssociative; associativity[4] = Associativity.LeftAssociative; associativity[5] = Associativity.LeftAssociative; associativity[6] = Associativity.LeftAssociative; associativity[7] = Associativity.NonAssociative; associativity[8] = Associativity.RightAssociative; } /// /// Whether the input text is an operator or not /// /// /// public static bool Contains(string oper) { return precedence.ContainsKey(oper); } /// /// whether operLeft has higher precedence than operRight /// /// /// /// public static bool IsPrior(string operLeft, string operRight) { if (operLeft == null) return false; if (operRight == null) return true; int priLeft = precedence[operLeft]; int priRight = precedence[operRight]; if (priLeft > priRight) { return true; } else if (priLeft < priRight) { return false; } else { switch (associativity[priLeft]) { case Associativity.LeftAssociative: return true; case Associativity.RightAssociative: return false; default: return true; } } } } }