PRINTの構文解析を一応実�
This commit is contained in:
@@ -3,8 +3,14 @@ import otya.smilebasic.parser;
|
|||||||
int main(string[] argv)
|
int main(string[] argv)
|
||||||
{
|
{
|
||||||
writeln("Hello D-World!");
|
writeln("Hello D-World!");
|
||||||
auto parser = new Parser("ADD(ADD(1,2,3,4,5,6),2,3,4,5,6)");
|
version(none)
|
||||||
writeln(parser.calc());
|
{
|
||||||
|
auto parser = new Parser("ADD(ADD(1,2,3,4,5,6),2,3,4,5,6)");
|
||||||
|
writeln(parser.calc());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto parser = new Parser("PRINT 1+1");
|
||||||
|
parser.compile();
|
||||||
readln();
|
readln();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ class VoidExpression : Expression
|
|||||||
}
|
}
|
||||||
abstract class Statement : Node
|
abstract class Statement : Node
|
||||||
{
|
{
|
||||||
|
static Statement NOP = null;
|
||||||
}
|
}
|
||||||
class Statements : Statement
|
class Statements : Statement
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class Lexical
|
|||||||
TokenType[wstring] reserved;
|
TokenType[wstring] reserved;
|
||||||
wstring code;
|
wstring code;
|
||||||
int index;
|
int index;
|
||||||
|
int line;
|
||||||
this(wstring input)
|
this(wstring input)
|
||||||
{
|
{
|
||||||
this.code = input;
|
this.code = input;
|
||||||
@@ -27,12 +28,15 @@ class Lexical
|
|||||||
table[','] = TokenType.Comma;
|
table[','] = TokenType.Comma;
|
||||||
table[':'] = TokenType.Colon;
|
table[':'] = TokenType.Colon;
|
||||||
table[';'] = TokenType.Semicolon;
|
table[';'] = TokenType.Semicolon;
|
||||||
|
table['\r'] = TokenType.NewLine;
|
||||||
|
table['\n'] = TokenType.NewLine;
|
||||||
reserved["OR"] = TokenType.Or;
|
reserved["OR"] = TokenType.Or;
|
||||||
reserved["AND"] = TokenType.And;
|
reserved["AND"] = TokenType.And;
|
||||||
reserved["XOR"] = TokenType.Xor;
|
reserved["XOR"] = TokenType.Xor;
|
||||||
reserved["NOT"] = TokenType.Not;
|
reserved["NOT"] = TokenType.Not;
|
||||||
reserved["PRINT"] = TokenType.Print;
|
reserved["PRINT"] = TokenType.Print;
|
||||||
reserved.rehash();
|
reserved.rehash();
|
||||||
|
line = 1;
|
||||||
}
|
}
|
||||||
bool empty()
|
bool empty()
|
||||||
{
|
{
|
||||||
@@ -104,6 +108,18 @@ class Lexical
|
|||||||
}
|
}
|
||||||
token = Token(table[cast(char)c]);
|
token = Token(table[cast(char)c]);
|
||||||
i++;
|
i++;
|
||||||
|
if(token.type == TokenType.NewLine)
|
||||||
|
{
|
||||||
|
line++;
|
||||||
|
if(c == '\n')
|
||||||
|
{
|
||||||
|
//CRLF
|
||||||
|
if(i < code.length && code[i] == '\r')
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
index = i;
|
index = i;
|
||||||
@@ -112,6 +128,10 @@ class Lexical
|
|||||||
{
|
{
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
int getLine()
|
||||||
|
{
|
||||||
|
return line;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
@@ -238,15 +258,84 @@ class Parser
|
|||||||
return - - -1;
|
return - - -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void compile()
|
||||||
|
{
|
||||||
|
}
|
||||||
Statements parseProgram()
|
Statements parseProgram()
|
||||||
{
|
{
|
||||||
auto statements = new Statements();
|
auto statements = new Statements();
|
||||||
statement();
|
while(!lex.empty())
|
||||||
|
{
|
||||||
|
//if token == DEF
|
||||||
|
//
|
||||||
|
auto statement = statement();
|
||||||
|
if(statement != Statement.NOP)
|
||||||
|
{
|
||||||
|
statements.addStatement(statement);
|
||||||
|
}
|
||||||
|
}
|
||||||
return statements;
|
return statements;
|
||||||
}
|
}
|
||||||
|
void syntaxError()
|
||||||
|
{
|
||||||
|
stderr.writeln("Syntax error", lex.getLine());
|
||||||
|
}
|
||||||
//statement
|
//statement
|
||||||
Statement statement()
|
Statement statement()
|
||||||
{
|
{
|
||||||
|
lex.popFront();
|
||||||
|
auto token = lex.front();
|
||||||
|
switch(token.type)
|
||||||
|
{
|
||||||
|
case TokenType.Print:
|
||||||
|
{
|
||||||
|
auto print = new Print();
|
||||||
|
bool addline = true;
|
||||||
|
lex.popFront();
|
||||||
|
token = lex.front();
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
//3号から厳密になって必ずいる
|
||||||
|
if(token.type == TokenType.Colon || token.type == TokenType.NewLine)
|
||||||
|
{
|
||||||
|
print.addLine();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(token.type == TokenType.Semicolon)
|
||||||
|
{
|
||||||
|
addline = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(token.type == TokenType.Comma)
|
||||||
|
{
|
||||||
|
print.addTab();
|
||||||
|
addline = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
addline = true;
|
||||||
|
auto exp = expression();
|
||||||
|
if(exp is null)
|
||||||
|
{
|
||||||
|
syntaxError();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
print.addArgument(exp);
|
||||||
|
lex.popFront();
|
||||||
|
token = lex.front();
|
||||||
|
if(token.type != TokenType.Colon && token.type != TokenType.NewLine && token.type != TokenType.Semicolon && token.type != TokenType.Comma)
|
||||||
|
{
|
||||||
|
syntaxError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TokenType.Colon:
|
||||||
|
case TokenType.NewLine:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
syntaxError();
|
||||||
|
break;
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Expression expression()
|
Expression expression()
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ enum TokenType
|
|||||||
Comma,
|
Comma,
|
||||||
Colon,
|
Colon,
|
||||||
Semicolon,
|
Semicolon,
|
||||||
|
NewLine,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Token
|
struct Token
|
||||||
|
|||||||
Reference in New Issue
Block a user