1
0

とりあえず構文木を一部作るようにして計算させた

This commit is contained in:
otya128
2015-06-03 20:59:47 +09:00
parent a74268b59a
commit bb9ae9abdc
4 changed files with 117 additions and 8 deletions

View File

@@ -1,7 +1,11 @@
import std.stdio; import std.stdio;
import otya.smilebasic.parser;
int main(string[] argv) int main(string[] argv)
{ {
writeln("Hello D-World!"); writeln("Hello D-World!");
auto parser = new Parser("1+2");
writeln();
writeln(parser.calc());
readln(); readln();
return 0; return 0;
} }

View File

@@ -3,7 +3,7 @@ import otya.smilebasic.type;
import otya.smilebasic.token; import otya.smilebasic.token;
enum NodeType enum NodeType
{ {
Node = 0b1, Node,
Expression, Expression,
Constant, Constant,
BinaryOperator, BinaryOperator,
@@ -20,6 +20,7 @@ class Constant : Expression
Value value; Value value;
this(Value v) this(Value v)
{ {
this.type = NodeType.Constant;
this.value = v; this.value = v;
} }
} }
@@ -28,6 +29,12 @@ class BinaryOperator : Expression
Expression item1; Expression item1;
TokenType operator; TokenType operator;
Expression item2; Expression item2;
this(Expression i1, TokenType o)
{
this.type = NodeType.BinaryOperator;
this.item1 = i1;
this.operator = o;
}
this(Expression i1, TokenType o, Expression i2) this(Expression i1, TokenType o, Expression i2)
{ {
this.type = NodeType.BinaryOperator; this.type = NodeType.BinaryOperator;

View File

@@ -3,13 +3,24 @@ import otya.smilebasic.token;
import otya.smilebasic.type; import otya.smilebasic.type;
import otya.smilebasic.node; import otya.smilebasic.node;
import std.ascii; import std.ascii;
import std.stdio;
class Lexical class Lexical
{ {
TokenType[] table;
wstring code; wstring code;
int index; int index;
this(wstring input) this(wstring input)
{ {
this.code = input; this.code = input;
table = new TokenType[256];
for(int i = 0;i<256;i++)
{
table[i] = TokenType.Unknown;
}
table['+'] = TokenType.Plus;
table['-'] = TokenType.Minus;
table['*'] = TokenType.Mul;
table['/'] = TokenType.Div;
} }
bool empty() bool empty()
{ {
@@ -18,6 +29,11 @@ class Lexical
Token token; Token token;
void popFront() void popFront()
{ {
if(empty())
{
token = Token(TokenType.Unknown);
return;
}
int i = index; int i = index;
for(;i < code.length;i++) for(;i < code.length;i++)
{ {
@@ -38,8 +54,12 @@ class Lexical
token = Token(TokenType.Integer, Value(num)); token = Token(TokenType.Integer, Value(num));
break; break;
} }
//error if(table[cast(char)c] == TokenType.Unknown)
{
//error
}
token = Token(table[cast(char)c]);
i++;
break; break;
} }
index = i; index = i;
@@ -111,19 +131,93 @@ class Parser
return 4;//+,-(bin) return 4;//+,-(bin)
case TokenType.Mul: case TokenType.Mul:
case TokenType.Div: case TokenType.Div:
// return 3;//*,/,DIV,MOD return 3;//*,/,DIV,MOD
// return 2;//-,NOT,! // return 2;//-,NOT,!
// return 1;//() // return 1;//()
default: default:
return 0;//TODO:エラーにすべきかは実装次第 return 0;//TODO:エラーにすべきかは実装次第
} }
} }
void expression(Expression node) int calc()
{ {
term(8, node); auto exp = expression();
return calc(exp);
} }
void term(int order, Expression node) int calc(Expression exp)
{ {
switch(exp.type)
{
case NodeType.Constant:
return (cast(Constant)exp).value.integerValue;
case NodeType.BinaryOperator:
{
auto binop = cast(BinaryOperator)exp;
auto i1 = calc(binop.item1);
auto i2 = calc(binop.item2);
switch(binop.operator)
{
case TokenType.Plus:
return i1 + i2;
case TokenType.Minus:
return i1 - i2;
case TokenType.Mul:
return i1 * i2;
case TokenType.Div:
return i1 / i2;
default:
return - - -1;
}
}
break;
default:
return - - -1;
}
}
Expression expression()
{
Expression node = null;
lex.popFront();
return term(8, node);
}
Expression term(int order, Expression node)
{
if(order == 1)
{
return factor();
}
Expression exp = term(order - 1, node);
auto token = lex.front();
if(order == getOPRank(token.type))
{
BinaryOperator op = new BinaryOperator(exp, token.type);
while(order == getOPRank(token.type))
{
auto tt = token.type;
lex.popFront();
op.item2 = term(order - 1, node);
token = lex.front();
write(tt, " ");
stdout.flush();
}
return op;
}
return exp;
}
Expression factor()
{
auto token = lex.front();
Expression node = null;
switch(token.type)
{
case TokenType.Integer:
write(token.value.integerValue, ' ');
stdout.flush();
node = new Constant(Value(token.value.integerValue));
break;
default:
return node;
}
if(!lex.empty())lex.popFront();
return node;
} }
} }

View File

@@ -27,4 +27,8 @@ struct Token
type = t; type = t;
value = v; value = v;
} }
this(TokenType t)
{
type = t;
}
} }