toker.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #include "std.h"
  2. #include <cctype>
  3. #include "toker.h"
  4. #include "ex.h"
  5. int Toker::chars_toked;
  6. static map<string,int> alphaTokes,lowerTokes;
  7. static void makeKeywords(){
  8. static bool made;
  9. if( made ) return;
  10. alphaTokes["Dim"]=DIM;
  11. alphaTokes["Goto"]=GOTO;
  12. alphaTokes["Gosub"]=GOSUB;
  13. alphaTokes["Return"]=RETURN;
  14. alphaTokes["Exit"]=EXIT;
  15. alphaTokes["If"]=IF;
  16. alphaTokes["Then"]=THEN;
  17. alphaTokes["Else"]=ELSE;
  18. alphaTokes["EndIf"]=ENDIF;
  19. alphaTokes["End If"]=ENDIF;
  20. alphaTokes["ElseIf"]=ELSEIF;
  21. alphaTokes["Else If"]=ELSEIF;
  22. alphaTokes["While"]=WHILE;
  23. alphaTokes["Wend"]=WEND;
  24. alphaTokes["For"]=FOR;
  25. alphaTokes["To"]=TO;
  26. alphaTokes["Step"]=STEP;
  27. alphaTokes["Next"]=NEXT;
  28. alphaTokes["Function"]=FUNCTION;
  29. alphaTokes["End Function"]=ENDFUNCTION;
  30. alphaTokes["Type"]=TYPE;
  31. alphaTokes["End Type"]=ENDTYPE;
  32. alphaTokes["Each"]=EACH;
  33. alphaTokes["Local"]=LOCAL;
  34. alphaTokes["Global"]=GLOBAL;
  35. alphaTokes["Field"]=FIELD;
  36. alphaTokes["Const"]=BBCONST;
  37. alphaTokes["Select"]=SELECT;
  38. alphaTokes["Case"]=CASE;
  39. alphaTokes["Default"]=DEFAULT;
  40. alphaTokes["End Select"]=ENDSELECT;
  41. alphaTokes["Repeat"]=REPEAT;
  42. alphaTokes["Until"]=UNTIL;
  43. alphaTokes["Forever"]=FOREVER;
  44. alphaTokes["Data"]=DATA;
  45. alphaTokes["Read"]=READ;
  46. alphaTokes["Restore"]=RESTORE;
  47. alphaTokes["Abs"]=ABS;
  48. alphaTokes["Sgn"]=SGN;
  49. alphaTokes["Mod"]=MOD;
  50. alphaTokes["Pi"]=PI;
  51. alphaTokes["True"]=BBTRUE;
  52. alphaTokes["False"]=BBFALSE;
  53. alphaTokes["Int"]=BBINT;
  54. alphaTokes["Float"]=BBFLOAT;
  55. alphaTokes["Str"]=BBSTR;
  56. alphaTokes["Include"]=INCLUDE;
  57. alphaTokes["New"]=BBNEW;
  58. alphaTokes["Delete"]=BBDELETE;
  59. alphaTokes["First"]=FIRST;
  60. alphaTokes["Last"]=LAST;
  61. alphaTokes["Insert"]=INSERT;
  62. alphaTokes["Before"]=BEFORE;
  63. alphaTokes["After"]=AFTER;
  64. alphaTokes["Null"]=BBNULL;
  65. alphaTokes["Object"]=OBJECT;
  66. alphaTokes["Handle"]=BBHANDLE;
  67. alphaTokes["And"]=AND;
  68. alphaTokes["Or"]=OR;
  69. alphaTokes["Xor"]=XOR;
  70. alphaTokes["Not"]=NOT;
  71. alphaTokes["Shl"]=SHL;
  72. alphaTokes["Shr"]=SHR;
  73. alphaTokes["Sar"]=SAR;
  74. map<string,int>::const_iterator it;
  75. for( it=alphaTokes.begin();it!=alphaTokes.end();++it ){
  76. lowerTokes[tolower(it->first)]=it->second;
  77. }
  78. made=true;
  79. }
  80. Toker::Toker( istream &in ):in(in),curr_row(-1){
  81. makeKeywords();
  82. nextline();
  83. }
  84. map<string,int> &Toker::getKeywords(){
  85. makeKeywords();
  86. return alphaTokes;
  87. }
  88. int Toker::pos(){
  89. return ((curr_row)<<16)|(tokes[curr_toke].from);
  90. }
  91. int Toker::curr(){
  92. return tokes[curr_toke].n;
  93. }
  94. string Toker::text(){
  95. int from=tokes[curr_toke].from,to=tokes[curr_toke].to;
  96. return line.substr( from,to-from );
  97. }
  98. int Toker::lookAhead( int n ){
  99. return tokes[curr_toke+n].n;
  100. }
  101. void Toker::nextline(){
  102. ++curr_row;
  103. curr_toke=0;
  104. tokes.clear();
  105. if( in.eof() ){
  106. line.resize(1);line[0]=EOF;
  107. tokes.push_back( Toke( EOF,0,1 ) );
  108. return;
  109. }
  110. getline( in,line );line+='\n';
  111. chars_toked+=line.size();
  112. for( int k=0;k<line.size(); ){
  113. int c=line[k],from=k;
  114. if( c=='\n' ){
  115. tokes.push_back( Toke( c,from,++k ) );
  116. continue;
  117. }
  118. if( isspace( c ) ){ ++k;continue; }
  119. if( c==';' ){
  120. for( ++k;line[k]!='\n';++k ){}
  121. continue;
  122. }
  123. if( c=='.' && isdigit( line[k+1] ) ){
  124. for( k+=2;isdigit( line[k] );++k ){}
  125. tokes.push_back( Toke( FLOATCONST,from,k ) );
  126. continue;
  127. }
  128. if( isdigit( c ) ){
  129. for( ++k;isdigit( line[k] );++k ){}
  130. if( line[k]=='.' ){
  131. for( ++k;isdigit( line[k] );++k ){}
  132. tokes.push_back( Toke( FLOATCONST,from,k ) );
  133. continue;
  134. }
  135. tokes.push_back( Toke( INTCONST,from,k ) );
  136. continue;
  137. }
  138. if( c=='%' && (line[k+1]=='0' || line[k+1]=='1') ){
  139. for( k+=2;line[k]=='0'||line[k]=='1';++k ){}
  140. tokes.push_back( Toke( BINCONST,from,k ) );
  141. continue;
  142. }
  143. if( c=='$' && isxdigit( line[k+1] ) ){
  144. for( k+=2;isxdigit( line[k] );++k ){}
  145. tokes.push_back( Toke( HEXCONST,from,k ) );
  146. continue;
  147. }
  148. if( isalpha( c ) ){
  149. for( ++k;isalnum( line[k] ) || line[k]=='_';++k ){}
  150. string ident=tolower(line.substr(from,k-from));
  151. if( line[k]==' ' && isalpha( line[k+1] ) ){
  152. int t=k;
  153. for( t+=2;isalnum( line[t] ) || line[t]=='_';++t ){}
  154. string s=tolower(line.substr(from,t-from));
  155. if( lowerTokes.find(s)!=lowerTokes.end() ){
  156. k=t;ident=s;
  157. }
  158. }
  159. map<string,int>::iterator it=lowerTokes.find( ident );
  160. if( it==lowerTokes.end() ){
  161. for( int n=from;n<k;++n ) line[n]=tolower(line[n]);
  162. tokes.push_back( Toke( IDENT,from,k ) );
  163. continue;
  164. }
  165. tokes.push_back( Toke( it->second,from,k ) );
  166. continue;
  167. }
  168. if( c=='\"' ){
  169. for( ++k;line[k]!='\"' && line[k]!='\n';++k ){}
  170. if( line[k]=='\"' ) ++k;
  171. tokes.push_back( Toke( STRINGCONST,from,k ) );
  172. continue;
  173. }
  174. int n=line[k+1];
  175. if( (c=='<'&&n=='>')||(c=='>'&&n=='<') ){
  176. tokes.push_back( Toke( NE,from,k+=2 ) );
  177. continue;
  178. }
  179. if( (c=='<'&&n=='=')||(c=='='&&n=='<') ){
  180. tokes.push_back( Toke( LE,from,k+=2 ) );
  181. continue;
  182. }
  183. if( (c=='>'&&n=='=')||(c=='='&&n=='>') ){
  184. tokes.push_back( Toke( GE,from,k+=2 ) );
  185. continue;
  186. }
  187. tokes.push_back( Toke( c,from,++k ) );
  188. }
  189. if( !tokes.size() ) exit(0);
  190. }
  191. int Toker::next(){
  192. if( ++curr_toke==tokes.size() ) nextline();
  193. return curr();
  194. }