Last active
April 13, 2017 05:05
-
-
Save CallumCarmicheal/a5e28888bccfc8afa004482f44a2b9f7 to your computer and use it in GitHub Desktop.
Expression example for a lexor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
List<string> GetGrath() { | |
Expression current_operation = null; | |
List<string> nodeString = new List<string>(); | |
Expression current_operation = null; | |
double output = 0; | |
var nodeCount = Nodes.Count(); | |
for (int i = 0; i < nodeCount; i++) { | |
Expression ex = Nodes[i]; | |
// Check if the node has next 2 | |
// IsNumberValue means if it is a number | |
// constant or anything that can be evaluated | |
// to a value | |
if (nodeCount >= i+2 && ex.IsNumberValue) { | |
var op = Nodes[i+1]; | |
var val = Nodes[i+2].GetValue(); | |
// Solve the problem of | |
// 5 + + 5 | |
// Expression error | |
if (op.isOperator && val.IsOperator) | |
throw new Exception($"Invalid syntax"); | |
// Invalid | |
// Syntax: 5 5 + 3 | |
if (!op.IsOperator) | |
throw new Exception($"Invalid syntax"); | |
// Check if the operator is a preceeding operator | |
if (op.IsPreceedingOperator) { | |
// Skip 2 operations | |
// the op and the val | |
i += 2; | |
// Show the calculation | |
nodeString.Add(op); | |
nodeString.Add("|- " + ex); | |
nodeString.Add("|- " + val); | |
} | |
} | |
if (cnt != 0) { | |
if (ex.IsOperator) { | |
if (Nodes[cnt-1].IsOperator) { | |
// Check if previous node was a expression | |
throw new Exception($"Invalid syntax"); | |
} | |
nodeString.Add(op); | |
continue; | |
} | |
} | |
nodeString.Add(ex); | |
} | |
return nodeString; | |
} | |
double GetValue() { | |
Expression current_operation = null; | |
Expression current_operation = null; | |
double output = 0; | |
var nodeCount = Nodes.Count(); | |
for (int i = 0; i < nodeCount; i++) { | |
Expression ex = Nodes[i]; | |
// Check if the node has next 2 | |
// IsNumberValue means if it is a number | |
// constant or anything that can be evaluated | |
// to a value | |
if (nodeCount >= i+2 && ex.IsNumberValue) { | |
var op = Nodes[i+1]; | |
var val = Nodes[i+2].GetValue(); | |
// Solve the problem of | |
// 5 + + 5 | |
// Expression error | |
if (op.isOperator && val.IsOperator) | |
throw new Exception($"Invalid syntax"); | |
// Invalid | |
// Syntax: 5 5 + 3 | |
if (!op.IsOperator) | |
throw new Exception($"Invalid syntax"); | |
// Check if the operator is a preceeding operator | |
if (op.IsPreceedingOperator) { | |
// Skip 2 operations | |
// the op and the val | |
i += 2; | |
// Run the calculation | |
var cVal = ex.GetValue(); | |
cVal = op.RunOperation(val, cVal); | |
output += cVal; | |
} | |
} | |
// Check if 2 operators right next to each other | |
// Syntax: 5 + + 3 or 5 5 + 3 | |
if (cnt != 0 && nodeCount >= i+1) { | |
if (ex.IsOperator && Nodes[cnt-1].IsOperator) { | |
// Check if previous node was a expression | |
throw new Exception($"Invalid syntax"); | |
} | |
else if (ex.IsNumberValue && Nodes[cnt-1].IsNumberValue) { | |
throw new Exception($"Invalid syntax"); | |
} | |
} | |
// We are a number, constant, variable or operator | |
string expression = ex.GetString(); | |
double result = 0; | |
// Check if expression/function | |
if (expression.IsConstant) { | |
// get value for constant in expression string | |
result = Constant.GetValueFor(expression); | |
} else if (expression.IsVariable) { | |
result = Variables.GetValueFor(Expression); | |
} | |
try { | |
// Try to parse | |
double.TryParse(expression, out result); | |
} catch (Exception ex) { | |
// Throw the error | |
throw new Exception($"Failed to parse {raw_number} into a double number"); | |
} | |
// RunOperation(int value, int currentOutput) | |
// this will check the operator and then | |
// do the calculation | |
// in the lexor you would want to | |
// have RunOperation overwritten by | |
// AddOperation : Operator | |
// MinusOpertion : Operator ... | |
output = current_operation.RunOperation(result, output); | |
} | |
return output; | |
} | |
class Operator : Expression { | |
public Operator() { | |
this.IsOperation = true; | |
} | |
public override double RunOperation(double val, double currentStack) { | |
throw new NotImplementedException(); | |
} | |
} | |
class AddOperator : Operator { | |
public AddOperator() : base() {} | |
public override double RunOperation(double value, double currentStack) { | |
return currentStack + value; | |
} | |
} | |
class SubOperator : Operator { | |
public SubOperator() : base() {} | |
public override double RunOperation(double val, double currentStack) { | |
return currentStack - val; | |
} | |
} | |
class MulitplyOperator : Operator { | |
public MulitplyOperator() : base() {} | |
public override double RunOperation(double val, double currentStack) { | |
return currentStack * val; | |
} | |
} | |
class DevideOperator : Operator { | |
public DevideOperator() : base() {} | |
public override double RunOperation(double val, double currentStack) { | |
return currentStack * val; | |
} | |
} | |
class PowerOperator : Operator { | |
public DevideOperator() : base() {} | |
public override double RunOperation(double val, double currentStack) { | |
return Math.Pow ( currentStack, val ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment