Skip to content

Commit

Permalink
括弧付きの式に対応
Browse files Browse the repository at this point in the history
  • Loading branch information
corgi0901 committed Aug 2, 2020
1 parent 6a5f33c commit 47d1b06
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 9 deletions.
3 changes: 2 additions & 1 deletion BNF.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
program = add
add = mul ("+" mul | "-" mul)*
mul = num ("*" num | "/" num)*
mul = primary ("*" primary | "/" primary)*
primary = num | "(" add ")"
30 changes: 27 additions & 3 deletions parser.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <vector>
#include "parser.hpp"
#include "rook.hpp"
Expand Down Expand Up @@ -39,21 +40,33 @@ Node* Parser::add(void)

Node* Parser::mul(void)
{
Node* node = num();
Node* node = primary();

while(1){
if(consume("*")){
node = new Node{ ND_MUL, node, num() };
node = new Node{ ND_MUL, node, primary() };
}
else if(consume("/")){
node = new Node{ ND_DIV, node, num() };
node = new Node{ ND_DIV, node, primary() };
}
else{
return node;
}
}
};

Node* Parser::primary(void)
{
if(consume("(")){
Node* addNode = add();
expect(")");
return addNode;
}
else{
return num();
}
};

bool Parser::consume(const char* str)
{
if(TK_EOF == token->kind) return false;
Expand All @@ -66,6 +79,17 @@ bool Parser::consume(const char* str)
return false;
};

void Parser::expect(const char* str)
{
if(TK_EOF == token->kind || strncmp(str, token->str, token->len)){
cerr << "Error : expect \"" << str << "\"" << endl;
exit(1);
}
else{
token++;
}
};

Node* Parser::parse(vector<Token>& tokens)
{
token = tokens.begin();
Expand Down
2 changes: 2 additions & 0 deletions parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ class Parser
Node* num(void);
Node* add(void);
Node* mul(void);
Node* primary(void);

bool consume(const char* str);
void expect(const char* str);

public:
Node* parse(vector<Token>& tokens);
Expand Down
2 changes: 1 addition & 1 deletion rook.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// トークン関連の定義
typedef enum {
TK_NUM, // 数値
TK_OP, // 演算子
TK_RESERVED, // 記号
TK_EOF, // 終端
} TokenKind;

Expand Down
4 changes: 4 additions & 0 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,9 @@ test 8 "2 * 4"
test 3 "12 / 4"
test 10 "5 * 3 - 5"
test 9 "2 + 2 * 5 - 3"
test 1 "(1)"
test 8 "2*(1+3)"
test 5 "1+(2*4)-(2*2)"
test 2 "(2*(1+1)+2)/3"

echo "OK"
18 changes: 14 additions & 4 deletions tokenizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,32 @@ vector<Token> Tokenizer::tokenize(char* input)
input++;
}
else if(strncmp(input, "+", 1) == 0){
Token token = { TK_OP, input, 1 };
Token token = { TK_RESERVED, input, 1 };
tokens.push_back(token);
input++;
}
else if(strncmp(input, "-", 1) == 0){
Token token = { TK_OP, input, 1 };
Token token = { TK_RESERVED, input, 1 };
tokens.push_back(token);
input++;
}
else if(strncmp(input, "*", 1) == 0){
Token token = { TK_OP, input, 1 };
Token token = { TK_RESERVED, input, 1 };
tokens.push_back(token);
input++;
}
else if(strncmp(input, "/", 1) == 0){
Token token = { TK_OP, input, 1 };
Token token = { TK_RESERVED, input, 1 };
tokens.push_back(token);
input++;
}
else if(strncmp(input, "(", 1) == 0){
Token token = { TK_RESERVED, input, 1 };
tokens.push_back(token);
input++;
}
else if(strncmp(input, ")", 1) == 0){
Token token = { TK_RESERVED, input, 1 };
tokens.push_back(token);
input++;
}
Expand Down

0 comments on commit 47d1b06

Please sign in to comment.