Skip to content

Instantly share code, notes, and snippets.

@satouuta
Forked from akouryy/gist:6307061
Last active December 21, 2015 12:49
Show Gist options
  • Save satouuta/6308128 to your computer and use it in GitHub Desktop.
Save satouuta/6308128 to your computer and use it in GitHub Desktop.
a
/* *
* Bython ver.0.0.0 *
* made by: *
* akouryy *
* hirorisuu *
* satouuta *
* */
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
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 | function) 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.push_back(expr1(program, option));
if(option->error){
return args;
}
while(1){
int val = expr1(program, option);
if(option->error){
return args;
}
args.push_back(val);
}
}
int function(string program, parse* option){
int old_index = option->index;
vector<int> args;
string fname = 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(fname == "exit" && args.empty()){
exit(0);
}else if(fname == "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);
if(option->error){
option->error = 0;
function(program, option);
}
}
skips(program, option);
return result;
}
int main(void){
while(1){
cout << "> ";
string s;
getline(cin, 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