From bb9ae9abdc73ff772a34ae92059e675c6081663d Mon Sep 17 00:00:00 2001 From: otya128 Date: Wed, 3 Jun 2015 20:59:47 +0900 Subject: [PATCH] =?UTF-8?q?=E3=81=A8=E3=82=8A=E3=81=82=E3=81=88=E3=81=9A?= =?UTF-8?q?=E6=A7=8B=E6=96=87=E6=9C=A8=E3=82=92=E4=B8=80=E9=83=A8=E4=BD=9C?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E3=81=97=E3=81=A6=E8=A8=88?= =?UTF-8?q?=E7=AE=97=E3=81=95=E3=81=9B=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SMILEBASIC/main.d | 4 ++ SMILEBASIC/node.d | 9 +++- SMILEBASIC/parser.d | 108 +++++++++++++++++++++++++++++++++++++++++--- SMILEBASIC/token.d | 4 ++ 4 files changed, 117 insertions(+), 8 deletions(-) diff --git a/SMILEBASIC/main.d b/SMILEBASIC/main.d index a3a7d60..c26e9be 100644 --- a/SMILEBASIC/main.d +++ b/SMILEBASIC/main.d @@ -1,7 +1,11 @@ import std.stdio; +import otya.smilebasic.parser; int main(string[] argv) { writeln("Hello D-World!"); + auto parser = new Parser("1+2"); + writeln(); + writeln(parser.calc()); readln(); return 0; } diff --git a/SMILEBASIC/node.d b/SMILEBASIC/node.d index c12e8e5..321c98f 100644 --- a/SMILEBASIC/node.d +++ b/SMILEBASIC/node.d @@ -3,7 +3,7 @@ import otya.smilebasic.type; import otya.smilebasic.token; enum NodeType { - Node = 0b1, + Node, Expression, Constant, BinaryOperator, @@ -20,6 +20,7 @@ class Constant : Expression Value value; this(Value v) { + this.type = NodeType.Constant; this.value = v; } } @@ -28,6 +29,12 @@ class BinaryOperator : Expression Expression item1; TokenType operator; 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.type = NodeType.BinaryOperator; diff --git a/SMILEBASIC/parser.d b/SMILEBASIC/parser.d index 32754ff..e8de6b8 100644 --- a/SMILEBASIC/parser.d +++ b/SMILEBASIC/parser.d @@ -3,13 +3,24 @@ import otya.smilebasic.token; import otya.smilebasic.type; import otya.smilebasic.node; import std.ascii; +import std.stdio; class Lexical { + TokenType[] table; wstring code; int index; this(wstring 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() { @@ -18,6 +29,11 @@ class Lexical Token token; void popFront() { + if(empty()) + { + token = Token(TokenType.Unknown); + return; + } int i = index; for(;i < code.length;i++) { @@ -38,8 +54,12 @@ class Lexical token = Token(TokenType.Integer, Value(num)); break; } - //error - + if(table[cast(char)c] == TokenType.Unknown) + { + //error + } + token = Token(table[cast(char)c]); + i++; break; } index = i; @@ -111,19 +131,93 @@ class Parser return 4;//+,-(bin) case TokenType.Mul: case TokenType.Div: -// return 3;//*,/,DIV,MOD + return 3;//*,/,DIV,MOD // return 2;//-,NOT,! // return 1;//() default: 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; } } diff --git a/SMILEBASIC/token.d b/SMILEBASIC/token.d index 532e3d3..4370c1d 100644 --- a/SMILEBASIC/token.d +++ b/SMILEBASIC/token.d @@ -27,4 +27,8 @@ struct Token type = t; value = v; } + this(TokenType t) + { + type = t; + } }