From 1c5cc21d72fcfe1df3637a5a4ed91185270f7ba3 Mon Sep 17 00:00:00 2001 From: Valk Richard Li <48872266+ValKmjolnir@users.noreply.github.com> Date: Wed, 18 Dec 2019 13:04:40 +0800 Subject: [PATCH] Update --- version2.0/abstract_syntax_tree.h | 80 +--------------- version2.0/nasal.h | 1 + version2.0/nasal_lexer.h | 65 +------------ version2.0/numeral_misc.h | 150 ++++++++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 140 deletions(-) create mode 100644 version2.0/numeral_misc.h diff --git a/version2.0/abstract_syntax_tree.h b/version2.0/abstract_syntax_tree.h index 2e7ebe0..68268fb 100644 --- a/version2.0/abstract_syntax_tree.h +++ b/version2.0/abstract_syntax_tree.h @@ -129,85 +129,9 @@ void abstract_syntax_tree::set_string(std::string __str) return; } -void abstract_syntax_tree::set_number(std::string _str) +void abstract_syntax_tree::set_number(std::string __str) { - bool is_negative=false; - if(_str.length()>1 && _str[0]=='-') - { - // this statements only used in "input" function - // but in parse this statements are useless - // because lexer recognizes a number that begins with a '0'~'9' char - std::string temp=""; - for(int i=1;i<_str.length();++i) - temp+=_str[i]; - _str=temp; - is_negative=true; - } - if((int)_str.length()>2 && (_str[1]=='x' || _str[1]=='o')) - { - double num=0; - double pw=1; - if(_str[1]=='x') // hex - for(int i=(int)_str.length()-1;i>1;--i) - { - if('0'<=_str[i] && _str[i]<='9') - num+=(_str[i]-'0')*pw; - else if('a'<=_str[i] && _str[i]<='f') - num+=(10+_str[i]-'a')*pw; - else if('A'<=_str[i] && _str[i]<='F') - num+=(10+_str[i]-'A')*pw; - pw*=16; - } - else // oct - for(int i=(int)_str.length()-1;i>1;--i) - { - num+=(_str[i]-'0')*pw; - pw*=8; - } - number=num; - if(is_negative) - number*=-1; - return; - } - int dot_place=-1; - for(int i=0;i<(int)_str.length();++i) - if(_str[i]=='.') - { - dot_place=i; - break; - } - if(dot_place==-1) - { - // integer - number=0; - double pw=1; - for(int i=(int)_str.length()-1;i>=0;--i) - { - number+=(_str[i]-'0')*pw; - pw*=10; - } - if(is_negative) - number*=-1; - } - else - { - // float - number=0; - double pw=0.1; - for(int i=dot_place+1;i<(int)_str.length();++i) - { - number+=(_str[i]-'0')*pw; - pw/=10; - } - pw=1; - for(int i=dot_place-1;i>=0;--i) - { - number+=(_str[i]-'0')*pw; - pw*=10; - } - if(is_negative) - number*=-1; - } + number=trans_string_to_number(__str); return; } diff --git a/version2.0/nasal.h b/version2.0/nasal.h index 369c96c..1a43514 100644 --- a/version2.0/nasal.h +++ b/version2.0/nasal.h @@ -10,6 +10,7 @@ #include #include +#include "numeral_misc.h" #include "nasal_enum.h" #include "abstract_syntax_tree.h" #include "nasal_lexer.h" diff --git a/version2.0/nasal_lexer.h b/version2.0/nasal_lexer.h index b0c61c0..fc7102c 100644 --- a/version2.0/nasal_lexer.h +++ b/version2.0/nasal_lexer.h @@ -22,7 +22,7 @@ example: 2147483647 (integer) 2.71828 (float) - 0xdeadbeef (hex) + 0xdeadbeef (hex) or 0xDEADBEEF (hex) 0o170001 (oct) __token_operator: ! + - * / ~ @@ -47,65 +47,6 @@ int is_reserve_word(std::string str) return __token_identifier; } -bool check_number(std::string str) -{ - if(str.length()>1 && str[0]=='-') - { - // this statements only used in "input" function - // but in lexer this statements are useless - // because lexer judge a number that begins with 0~9 (or 0x for hex & 0o for oct) - std::string temp=""; - for(int i=1;i=3 && str[0]=='0' && str[1]=='x') - { - for(int i=2;i=3 && str[0]=='0' && str[1]=='o') - { - for(int i=2;i1) - return false; - if(str[0]=='.') - return false; - if(!dotcnt && str[0]=='0') - return false; - return true; - } - return false; -} - class resource_file { private: @@ -322,10 +263,10 @@ class nasal_lexer if(ptr==res.end()) break; } - if(!check_number(token_str)) + if(!check_numerable_string(token_str)) { ++error; - std::cout<<">>[Lexer-error] line "<>[Lexer-error] line "<1 && str[0]=='-') + { + // in lexer this statements are useless + // because lexer judge a number that begins with 0~9 (or 0x for hex & 0o for oct) + std::string temp=""; + int str_len=str.length(); + for(int i=1;i2 && str[0]=='0' && str[1]=='x') + { + int str_len=str.length(); + for(int i=2;i2 && str[0]=='0' && str[1]=='o') + { + int str_len=str.length(); + for(int i=2;i1) || (str[0]=='.') || (!float_dot_cnt && str[0]=='0')) + return false; + return true; + } + return false; +} +double trans_string_to_number(std::string str) +{ + bool is_negative=false; + if(str.length()>1 && str[0]=='-') + { + // in parse this statements are useless + // because lexer recognizes a number that begins with a '0'~'9' char + std::string temp=""; + int str_len=str.length(); + for(int i=1;i1;--i) + { + if('0'<=str[i] && str[i]<='9') + hex_number+=bit_pow*(str[i]-'0'); + else if('a'<=str[i] && str[i]<='f') + hex_number+=bit_pow*(10+str[i]-'a'); + else + hex_number+=bit_pow*(10+str[i]-'A'); + bit_pow<<=4; + } + trans_str_number=(double)hex_number; + } + else if(str[0]=='0' && str[1]=='o') + { + long long int oct_number=0,bit_pow=1; + for(int i=str.length()-1;i>1;--i) + { + oct_number+=bit_pow*(str[i]-'0'); + bit_pow<<=3; + } + trans_str_number=(double)oct_number; + } + else + { + int float_dot_place=str.length(); + int str_len=str.length(); + double pow; + for(int i=0;i=0;--i) + { + trans_str_number+=pow*(double(str[i]-'0')); + pow*=10; + } + } + if(is_negative) + trans_str_number*=-1; + return trans_str_number; +} +std::string trans_number_to_string(double number) +{ + std::string trans_num_string=""; + if(number<0) + { + trans_num_string+='-'; + number*=-1; + } + double integer_bit=1; + while(number>=integer_bit) + integer_bit*=10; + integer_bit/=10; + while(integer_bit!=0.1) + { + trans_num_string+=(char)('0'+(int(number/integer_bit))); + number-=(double)(int(number/integer_bit))*integer_bit; + integer_bit/=10; + } + if(number!=0) + trans_num_string+='.'; + while(number!=0) + { + trans_num_string+=(char)('0'+int(number*10)); + number*=10; + number-=(double)(int(number)); + } + return trans_num_string; +} + +#endif