Skip to content

Instantly share code, notes, and snippets.

@CallumCarmicheal
Last active April 13, 2017 05:05
Show Gist options
  • Save CallumCarmicheal/a5e28888bccfc8afa004482f44a2b9f7 to your computer and use it in GitHub Desktop.
Save CallumCarmicheal/a5e28888bccfc8afa004482f44a2b9f7 to your computer and use it in GitHub Desktop.
Expression example for a lexor
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