/// <summary> /// Parses a label /// </summary> public static Label ParseLabel(Scanner scanner) { Token t = scanner.nextToken(); if (t.Type != TokenType.Identifier) { throw new Exception("Identifier expected: " + t); } String name = t.StringValue; StringBuilder str = new StringBuilder(); t = scanner.peekToken(); if (t.Type == TokenType.LParen) { // ( scanner.nextToken(); t = scanner.peekToken(); if (t.Type != TokenType.RParen) { while (true) { t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.Type != TokenType.Integer) { throw new Exception("Identifier or integer expected: " + t); } str.Append(t.StringValue); // ) or , t = scanner.nextToken(); if (t.Type == TokenType.RParen) { break; } if (t.Type != TokenType.Comma) { throw new Exception(", expected: " + t); } str.Append(','); } } else { // ) scanner.nextToken(); } } return(new Label(name, str.ToString())); }
// Loads definitions for variables private void LoadVariables(Scanner s) { variables = new Dictionary <string, Definition>(); while (true) { Token t = s.peekToken(); if (t.Type == TokenType.EOF) { break; } if (t.Type == TokenType.Identifier && t.StringValue == "end") { // end s.nextToken(); break; } Definition def = ReadDefinition(s); if (def.set == null) { def.set = defaultSets[def.domain]; } variables.Add(def.name, def); } }
/// <summary> /// Parses a bound of a variable /// </summary> /// <param name="scanner"></param> /// <param name="lp"></param> private static void ParseBound(Scanner scanner, LP lp) { Label varName; // TODO: wrong way of dealing with free variables // because the name of a variable could be more complicated // than just one identifier Token t = scanner.peekToken(1); if (t.Type == TokenType.Identifier && t.StringValue == "free") { // name varName = Label.ParseLabel(scanner); lp.vars.AddVariable(varName); // free t = scanner.nextToken(); return; } // Lower bound t = scanner.nextToken(); if (t.Type != TokenType.Integer && t.Type != TokenType.Double) { throw new Exception("A number is expected: " + t); } decimal low = decimal.Parse(t.StringValue); // <= t = scanner.nextToken(); if (t.Type != TokenType.Le) { throw new Exception("<= expected: " + t); } // Variable varName = Label.ParseLabel(scanner); // <= t = scanner.nextToken(); if (t.Type != TokenType.Le) { throw new Exception("<= expected: " + t); } // Upper bound t = scanner.nextToken(); if (t.Type != TokenType.Integer && t.Type != TokenType.Double) { throw new Exception("A number is expected: " + t); } decimal high = decimal.Parse(t.StringValue); lp.vars.AddVariable(varName); lp.vars[varName].LBound = low; lp.vars[varName].UBound = high; }
private Definition ReadDefinition(Scanner s) { // name Token t = s.nextToken(); if (t.Type != TokenType.Identifier) { throw new Exception("Identifier expected: " + t); } string name = t.StringValue; // : t = s.nextToken(); if (t.Type != TokenType.Colon) { throw new Exception(": expected: " + t); } // domain t = s.nextToken(); if (t.Type != TokenType.Identifier) { throw new Exception("Identifier expected: " + t); } string domain = t.StringValue; string set = null; t = s.peekToken(); if (t.Type == TokenType.Comma) { // , t = s.nextToken(); // set t = s.nextToken(); if (t.Type != TokenType.Identifier) { throw new Exception("Identifier expected: " + t); } set = t.StringValue; } return(new Definition(name, domain, set)); }
/// <summary> /// Parses a linear function /// </summary> /// <param name="scanner"></param> /// <returns></returns> public static LinearFunction ParseFunction(Scanner scanner) { LinearFunction f = new LinearFunction(); Token t; while (true) { t = scanner.peekToken(); if (t.Type != TokenType.Plus && t.Type != TokenType.Minus) { break; } Term term = Term.ParseTerm(scanner); f.terms.Add(term); } return(f); }
/// <summary> /// Parses a term /// </summary> /// <param name="scanner"></param> /// <returns></returns> public static Term ParseTerm(Scanner scanner) { Token t = scanner.nextToken(); bool negative = false; decimal c; Label varName; // Sign if (t.Type == TokenType.Minus) { negative = true; } else if (t.Type != TokenType.Plus) { throw new Exception("+ or - expected: " + t); } t = scanner.peekToken(); // Coefficient if (t.Type == TokenType.Integer || t.Type == TokenType.Double) { // number scanner.nextToken(); c = decimal.Parse(t.StringValue); } else { c = 1; } if (negative) { c = -c; } // Variable varName = Label.ParseLabel(scanner); return(new Term(new LpNumber(c), varName)); }
// Loads default sets private void LoadDefaultSets(Scanner s) { defaultSets = new Dictionary <string, string>(); while (true) { Token t = s.peekToken(); if (t.Type == TokenType.EOF) { break; } if (t.Type == TokenType.Identifier && t.StringValue == "end") { // end s.nextToken(); break; } Definition def = ReadDefinition(s); defaultSets.Add(def.name, def.domain); } }
/// <summary> /// Parses a LP /// </summary> /// <param name="scanner"></param> /// <returns></returns> public static LP ParseLP(Scanner scanner) { LP lp = new LP(); // Maximize Token t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.StringValue != "Maximize") { throw new Exception("Maximize expected: " + t); } // objective t = scanner.nextToken(); if (t.Type != TokenType.Identifier) { throw new Exception("Identifier expected: " + t); } // : t = scanner.nextToken(); if (t.Type != TokenType.Colon) { throw new Exception(": expected: " + t); } // objective function lp.objective = LinearFunction.ParseFunction(scanner); // Subject To t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.StringValue != "Subject") { throw new Exception("Subject To expected: " + t); } t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.StringValue != "To") { throw new Exception("Subject To expected: " + t); } // Constraints while (true) { t = scanner.peekToken(); if (t.Type == TokenType.Identifier && t.StringValue == "Bounds") { break; } if (t.Type == TokenType.EOF) { break; } Inequality ineq = Inequality.ParseInequality(scanner); lp.originalIneqs.Add(ineq); } // Bounds t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.StringValue != "Bounds") { throw new Exception("Bounds expected: " + t); } // Bounds while (true) { t = scanner.peekToken(); if (t.Type == TokenType.Identifier && t.StringValue == "End") { break; } if (t.Type == TokenType.EOF) { break; } ParseBound(scanner, lp); } return(lp); }
// Reads one definition private Definition ReadDefinition(Scanner s) { // name Token t = s.nextToken(); if (t.Type != TokenType.Identifier) throw new Exception("Identifier expected: " + t); string name = t.StringValue; // : t = s.nextToken(); if (t.Type != TokenType.Colon) throw new Exception(": expected: " + t); // domain t = s.nextToken(); if (t.Type != TokenType.Identifier) throw new Exception("Identifier expected: " + t); string domain = t.StringValue; string set = null; t = s.peekToken(); if (t.Type == TokenType.Comma) { // , t = s.nextToken(); // set t = s.nextToken(); if (t.Type != TokenType.Identifier) throw new Exception("Identifier expected: " + t); set = t.StringValue; } return new Definition(name, domain, set); }
// Loads definitions for variables private void LoadVariables(Scanner s) { variables = new Dictionary<string, Definition>(); while (true) { Token t = s.peekToken(); if (t.Type == TokenType.EOF) break; if (t.Type == TokenType.Identifier && t.StringValue == "end") { // end s.nextToken(); break; } Definition def = ReadDefinition(s); if (def.set == null) def.set = defaultSets[def.domain]; variables.Add(def.name, def); } }
// Loads default sets private void LoadDefaultSets(Scanner s) { defaultSets = new Dictionary<string, string>(); while (true) { Token t = s.peekToken(); if (t.Type == TokenType.EOF) break; if (t.Type == TokenType.Identifier && t.StringValue == "end") { // end s.nextToken(); break; } Definition def = ReadDefinition(s); defaultSets.Add(def.name, def.domain); } }
/// <summary> /// Parses a LP /// </summary> /// <param name="scanner"></param> /// <returns></returns> public static LP ParseLP(Scanner scanner) { LP lp = new LP(); // Maximize Token t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.StringValue != "Maximize") throw new Exception("Maximize expected: " + t); // objective t = scanner.nextToken(); if (t.Type != TokenType.Identifier) throw new Exception("Identifier expected: " + t); // : t = scanner.nextToken(); if (t.Type != TokenType.Colon) throw new Exception(": expected: " + t); // objective function lp.objective = LinearFunction.ParseFunction(scanner); // Subject To t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.StringValue != "Subject") throw new Exception("Subject To expected: " + t); t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.StringValue != "To") throw new Exception("Subject To expected: " + t); // Constraints while (true) { t = scanner.peekToken(); if (t.Type == TokenType.Identifier && t.StringValue == "Bounds") break; if (t.Type == TokenType.EOF) break; Inequality ineq = Inequality.ParseInequality(scanner); lp.originalIneqs.Add(ineq); } // Bounds t = scanner.nextToken(); if (t.Type != TokenType.Identifier && t.StringValue != "Bounds") throw new Exception("Bounds expected: " + t); // Bounds while (true) { t = scanner.peekToken(); if (t.Type == TokenType.Identifier && t.StringValue == "End") break; if (t.Type == TokenType.EOF) break; ParseBound(scanner, lp); } return lp; }
/// <summary> /// Parses a bound of a variable /// </summary> /// <param name="scanner"></param> /// <param name="lp"></param> private static void ParseBound(Scanner scanner, LP lp) { Label varName; // TODO: wrong way of dealing with free variables // because the name of a variable could be more complicated // than just one identifier Token t = scanner.peekToken(1); if (t.Type == TokenType.Identifier && t.StringValue == "free") { // name varName = Label.ParseLabel(scanner); lp.vars.AddVariable(varName); // free t = scanner.nextToken(); return; } // Lower bound t = scanner.nextToken(); if (t.Type != TokenType.Integer && t.Type != TokenType.Double) throw new Exception("A number is expected: " + t); decimal low = decimal.Parse(t.StringValue); // <= t = scanner.nextToken(); if (t.Type != TokenType.Le) throw new Exception("<= expected: " + t); // Variable varName = Label.ParseLabel(scanner); // <= t = scanner.nextToken(); if (t.Type != TokenType.Le) throw new Exception("<= expected: " + t); // Upper bound t = scanner.nextToken(); if (t.Type != TokenType.Integer && t.Type != TokenType.Double) throw new Exception("A number is expected: " + t); decimal high = decimal.Parse(t.StringValue); lp.vars.AddVariable(varName); lp.vars[varName].LBound = low; lp.vars[varName].UBound = high; }