-
-
Save akouryy/6307061 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* * | |
* Bython ver.0.0.0 * | |
* made by: * | |
* akouryy * | |
* hirorisuu * | |
* satouuta * | |
* */ | |
#include <iostream> | |
#include <sstream> | |
#include <string> | |
using namespace std; | |
typedef struct{ | |
int index; | |
int error; | |
} parse; | |
int expr1(string const, parse*); | |
int expr2(string const, parse*); | |
int expr3(string const, parse*); | |
/* | |
{0 to 9} ... number | |
S {a to z | A to Z | _} S ... name | |
[expr1 {, expr1}] ... funarg | |
name \( funarg \) ... function | |
expr2 {(+ | -) expr2} ... expr1 | |
expr3 {(* | /) expr3} ... expr2 | |
S (\( expr1 \) | number) S ... expr3 | |
*/ | |
string bython(string program){ | |
parse option = {0, 0}; | |
int ret = expr1(program, &option); | |
ostringstream stream; | |
stream << ret << "(" << option.error?"Error, ":"" << "index: " << option.index << ")"; | |
return stream.str(); | |
} | |
void skips(string const program, parse* option){ | |
while(program[option->index] == ' '){ | |
option->index++; | |
} | |
} | |
int number(string program, parse* option){ | |
int result = 0; | |
if(program[option->index] < '0' || '9' < program[option->index]){ | |
option->error = 1; | |
return 0; | |
} | |
while('0' <= program[option->index] && program[option->index] <= '9'){ | |
result = result * 10 + program[option->index] - '0'; | |
option->index++; | |
} | |
return result; | |
} | |
string name(string program, parse* option){ | |
if(!( 'a' <= program[option->index] && program[option->index] <= 'z' | |
|| 'A' <= program[option->index] && program[option->index] <= 'Z' | |
|| '_' == program[option->index])){ | |
option->error = 1; | |
return; | |
} | |
int old_index = option->index; | |
string result; | |
while( 'a' <= program[option->index] && program[option->index] <= 'z' | |
|| 'A' <= program[option->index] && program[option->index] <= 'Z' | |
|| '0' <= program[option->index] && program[option->index] <= '9' | |
|| '_' == program[option->index]){ | |
result += program[option->index]; | |
option->index++; | |
} | |
return result; | |
} | |
vector<int> funarg(string program, parse* option){ | |
vector<int> args; | |
args << expr1(program, option); | |
if(option->error){ | |
return 0; | |
} | |
while(1){ | |
int val = expr1(program, option) | |
if(option->error){ | |
return args; | |
} | |
args << val; | |
} | |
} | |
int function(string program, parse* option){ | |
int old_index = option->index; | |
vector<int> args; | |
string name = name(program, option); | |
if(program[option->index] == '('){ | |
option->index++; | |
args = funarg(program, option); | |
if(program[option->index] != ')'){ | |
option->index = old_index; | |
option->error = 1; | |
return 0; | |
} | |
option->index++; | |
}else{ | |
option->error = 1; | |
return 0; | |
} | |
if(name == "exit" && args.empty()){ | |
exit(0); | |
}else if(name == "exit" && args.size() == 1){ | |
exit(args(0)); | |
} | |
return 0; //TODO: 後で変える | |
} | |
int expr1(string program, parse* option){ | |
int result = expr2(program, option); | |
while(1){ | |
switch(program[option->index]){ | |
case '+': | |
option->index++; | |
result += expr2(program, option); | |
break; | |
case '-': | |
option->index++; | |
result -= expr2(program, option); | |
break; | |
default: | |
return result; | |
} | |
if(option->error){ | |
option->index--; | |
option->error=0; | |
return result; | |
} | |
} | |
} | |
int expr2(string program, parse* option){ | |
int result = expr3(program, option); | |
while(1){ | |
switch(program[option->index]){ | |
case '*': | |
option->index++; | |
result *= expr3(program, option); | |
break; | |
case '/': | |
option->index++; | |
result /= expr3(program, option); | |
break; | |
default: | |
return result; | |
} | |
if(option->error){ | |
option->index--; | |
option->error=0; | |
return result; | |
} | |
} | |
} | |
int expr3(string program, parse* option){ | |
int result = 0; | |
int old_index = option->index; | |
skips(program, option); | |
if(program[option->index] == '('){ | |
option->index++; | |
result = expr1(program, option); | |
if(program[option->index] != ')'){ | |
option->index = old_index; | |
option->error = 1; | |
return 0; | |
} | |
option->index++; | |
}else{ | |
result = number(program, option); | |
} | |
skips(program, option); | |
return result; | |
} | |
int main(void){ | |
while(1){ | |
cout << "> "; | |
string s; | |
getlines(cout, s); | |
if(!s.empty()){ | |
cout << bython(s) << endl; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment