Skip to content

Instantly share code, notes, and snippets.

@theoremoon
Created February 9, 2018 09:38
Show Gist options
  • Select an option

  • Save theoremoon/10c50734cbc94e2505cc19348edd6aea to your computer and use it in GitHub Desktop.

Select an option

Save theoremoon/10c50734cbc94e2505cc19348edd6aea to your computer and use it in GitHub Desktop.
import std.stdio;
struct Token
{
string name;
int type;
}
class Node {}
class NumNode : Node
{
public:
string v;
this (string v)
{
this.v = v;
}
override string toString()
{
return this.v;
}
}
class OpNode : Node
{
public:
string op;
Node[] args;
this (string op, Node[] args)
{
this.op = op;
this.args = args;
}
override string toString()
{
import std.array, std.algorithm, std.format, std.conv;
return "(%s %s)".format(this.op, this.args.map!(to!string).join(" "));
}
}
import std.range;
Node parseNum(ref Token[] tokens)
{
if (!tokens.empty && tokens.front.type == 0) {
auto n = new NumNode(tokens.front.name);
tokens.popFront();
return n;
}
return null;
}
Node parseMul(ref Token[] tokens)
{
Node left = tokens.parseNum();
if (left is null) { return null; }
while (! tokens.empty()) {
if (tokens.front.type != 1) { break; }
auto op = tokens.front.name;
tokens.popFront();
auto right = tokens.parseNum();
if (right is null) {
writeln(left);
throw new Exception("right hand operator is expected");
}
left = new OpNode(op, [left, right]);
}
return left;
}
Node parseAdd(ref Token[] tokens)
{
Node left = tokens.parseMul();
if (left is null) { return null; }
while (! tokens.empty()) {
if (tokens.front.type != 2) { break; }
auto op = tokens.front.name;
tokens.popFront();
auto right = tokens.parseMul();
if (right is null) {
throw new Exception("right hand operator is expected");
}
left = new OpNode(op, [left, right]);
}
return left;
}
void main()
{
auto input = [Token("1", 0), Token("+", 2), Token("2", 0), Token("+", 2), Token("3", 0)];
writeln(parseAdd(input));
}
(+ (+ 1 2) 3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment