ColorParser.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. #include "ColorParser.h"
  2. using namespace KSGScript;
  3. const char *(ColorParser::keyword[]) = { "lesen", "var", "func", "Rückruf", "class", "public", "private", "if", "else", "return", "break", "continue", "for", "while" };
  4. const int ColorParser::keywordAnz = 14;
  5. const char *( ColorParser::type[] ) = { "void", "bool", "int", "double", "Array", "Thread", "Text", "Bild", "MausEreignis", "TastaturEreignis", "TextFeld", "Knopf", "Fenster", "BildZ", "Animation2DData", "Animation2D" };
  6. const int ColorParser::typeAnz = 16;
  7. // Konstructor
  8. // zTxt: Der Text, der geparsed werden soll
  9. ColorParser::ColorParser( Text *zTxt )
  10. {
  11. pfad = new Text( "" );
  12. ref = 1;
  13. txt = zTxt->getThis();
  14. reset();
  15. reload();
  16. }
  17. // Destructor
  18. ColorParser::~ColorParser()
  19. {
  20. txt->release();
  21. }
  22. // behandelt einen Fehler
  23. void ColorParser::handleError( int begin, int ende )
  24. {
  25. if( errorIgnore )
  26. return;
  27. Error err;
  28. err.anfang = begin;
  29. err.ende = ende;
  30. error.add( err );
  31. }
  32. // Setzt den Parsevorgang zum Beginn zurück
  33. void ColorParser::reset()
  34. {
  35. pos.pos = 0;
  36. pos.inKeyword = 0;
  37. pos.inTypename = 0;
  38. pos.inParameter = 0;
  39. pos.inInstanzVar = 0;
  40. pos.inString = 0;
  41. pos.inChar = 0;
  42. pos.lastLehr = 1;
  43. pos.lastTrenner = 1;
  44. }
  45. // Lädt das Script neu
  46. void ColorParser::reload()
  47. {
  48. error.leeren();
  49. for( auto i = abschnitt.getArray(); i.set; i++ )
  50. {
  51. if( i.var.zFunktion )
  52. i.var.zFunktion->release();
  53. if( i.var.zKlasse )
  54. i.var.zKlasse->release();
  55. }
  56. abschnitt.leeren();
  57. delete dat;
  58. dat = new KSGSLeseScript();
  59. d = new TextReader( txt->getThis() );
  60. zeile = 1;
  61. while( !d->istEnde() )
  62. {
  63. bool br = 0;
  64. int id = leseNext();
  65. switch( id )
  66. {
  67. case -1: // Ende der Datei
  68. break;
  69. case 1: // Klasse
  70. if( 1 )
  71. {
  72. KSGSLeseKlasse *k = leseKlasse();
  73. if( !k )
  74. {
  75. //error( 6, { "Klasse", *pfad }, zObj );
  76. br = 1;
  77. }
  78. else
  79. dat->klassen.add( k );
  80. }
  81. break;
  82. case 2: // funktion
  83. if( 1 )
  84. {
  85. KSGSLeseFunktion *f = leseFunktion();
  86. if( !f )
  87. {
  88. //error( 6, { "Funktion", *pfad }, zObj );
  89. br = 1;
  90. }
  91. else
  92. dat->funktionen.add( f );
  93. }
  94. break;
  95. case 3: // Variable
  96. if( 1 )
  97. {
  98. KSGSLeseVariable *v = leseVariable();
  99. if( !v )
  100. {
  101. //error( 6, { "Variable", *pfad }, zObj );
  102. br = 1;
  103. }
  104. else
  105. dat->variablen.add( v );
  106. }
  107. break;
  108. case 12: // lesen
  109. if( 1 )
  110. {
  111. if( !leseBis( '(' ) )
  112. {
  113. //error( 6, { "Lade Anweisung", *pfad }, zObj );
  114. br = 1;
  115. break;
  116. }
  117. d->setLPosition( d->getLPosition() + 1, 0 );
  118. if( !leseBis( '"' ) )
  119. {
  120. //error( 6, { "Lade Anweisung", *pfad }, zObj );
  121. br = 1;
  122. break;
  123. }
  124. d->setLPosition( d->getLPosition() + 1, 0 );
  125. __int64 end = nextPosOf( '"', 0 );
  126. if( end < 0 )
  127. {
  128. //error( 6, { "Lade Anweisung", *pfad }, zObj );
  129. br = 1;
  130. break;
  131. }
  132. char *datei = new char[ (int)( end - d->getLPosition() ) + 1 ];
  133. datei[ end - d->getLPosition() ] = 0;
  134. d->lese( datei, (int)( end - d->getLPosition() ) );
  135. Text *dPf = new Text( datei );
  136. dPf->ersetzen( '\\', '/' );
  137. if( dPf->getText()[ 0 ] == '/' )
  138. dPf->remove( 0 );
  139. else
  140. dPf->insert( 0, wd->getText() );
  141. delete[] datei;
  142. if( !leseBis( ')' ) )
  143. {
  144. //error( 6, { "Lade Anweisung", *pfad }, zObj );
  145. br = 1;
  146. break;
  147. }
  148. d->setLPosition( d->getLPosition() + 1, 0 );
  149. Text *pf = new Text( pfad->getText() );
  150. pfad->setText( dPf );
  151. Reader *tmp = d;
  152. if( !ladeDatei() )
  153. {
  154. handleError( (int)d->getLPosition() - 1, (int)d->getLPosition() );
  155. d = tmp;
  156. pfad->setText( pf );
  157. //error( 6, { "Lade Anweisung", *pfad }, zObj );
  158. br = 1;
  159. break;
  160. }
  161. d = tmp;
  162. pfad->setText( pf );
  163. }
  164. break;
  165. default: // Fehler
  166. handleError( (int)d->getLPosition() - 1, (int)d->getLPosition() );
  167. //error( 5, { *pfad, Text() += zeile }, zObj );
  168. br = 1;
  169. break;
  170. }
  171. if( id == -1 )
  172. break;
  173. if( br )
  174. {
  175. //ok = 0;
  176. break;
  177. }
  178. }
  179. d = ( (TextReader*)d )->release();
  180. }
  181. KSGSLeseKlasse *ColorParser::leseKlasse()
  182. {
  183. Abschnitt abs;
  184. abs.anfang = (int)d->getLPosition();
  185. KSGSLeseKlasse *ret = __super::leseKlasse();
  186. abs.ende = (int)d->getLPosition();
  187. abs.zKlasse = ret;
  188. abs.zFunktion = 0;
  189. if( ret )
  190. ret->ref++;
  191. abschnitt.add( abs );
  192. return ret;
  193. }
  194. KSGSLeseFunktion *ColorParser::leseFunktion()
  195. {
  196. Abschnitt abs;
  197. abs.anfang = (int)d->getLPosition();
  198. KSGSLeseFunktion *ret = __super::leseFunktion();
  199. abs.ende = (int)d->getLPosition();
  200. abs.zKlasse = 0;
  201. abs.zFunktion = ret;
  202. if( ret )
  203. ret->ref++;
  204. abschnitt.add( abs );
  205. return ret;
  206. }
  207. // Gibt den Farbtyp des nächsten Zeichens zurück
  208. KSGScriptEditor::ColorType ColorParser::getNextColor( int &underlineC )
  209. {
  210. KSGScriptEditor::ColorType color = KSGScriptEditor::ColorType::NORMAL_TEXT;
  211. int scriptL = txt->getLength();
  212. char c = txt->getText()[ pos.pos++ ];
  213. bool inString = pos.inChar || pos.inString;
  214. if( c == '\'' && txt->getText()[ pos.pos - 2 ] != '\\' )
  215. pos.inChar = !pos.inChar;
  216. if( c == '"' && txt->getText()[ pos.pos - 2 ] != '\\' )
  217. pos.inString = !pos.inString;
  218. if( istLehr( c ) || istTrenner( c ) )
  219. {
  220. pos.inKeyword = 0;
  221. pos.inTypename = 0;
  222. pos.inInstanzVar = 0;
  223. pos.inParameter = 0;
  224. }
  225. else if( !pos.inChar && !pos.inString )
  226. {
  227. if( !pos.inInstanzVar && !pos.inParameter && !pos.inKeyword && !pos.inTypename && pos.lastLehr )
  228. {
  229. for( int i = 0; i < keywordAnz; i++ )
  230. {
  231. int kl = textLength( keyword[ i ] );
  232. pos.inKeyword = 1;
  233. for( int j = 0; j < kl && j + pos.pos <= scriptL && pos.inKeyword; j++ )
  234. pos.inKeyword &= txt->getText()[ j + pos.pos - 1 ] == keyword[ i ][ j ];
  235. if( pos.inKeyword && ( kl - 1 + pos.pos == scriptL || istTrenner( txt->getText()[ kl - 1 + pos.pos ] ) ) )
  236. break;
  237. pos.inKeyword = 0;
  238. }
  239. }
  240. if( !pos.inInstanzVar && !pos.inParameter && !pos.inKeyword && !pos.inTypename && pos.lastLehr )
  241. {
  242. for( int i = 0; i < typeAnz; i++ )
  243. {
  244. int tl = textLength( type[ i ] );
  245. pos.inTypename = 1;
  246. for( int j = 0; j < tl && j + pos.pos <= scriptL && pos.inTypename; j++ )
  247. pos.inTypename &= txt->getText()[ j + pos.pos - 1 ] == type[ i ][ j ];
  248. if( pos.inTypename && ( tl - 1 + pos.pos == scriptL || istTrenner( txt->getText()[ tl - 1 + pos.pos ] ) ) )
  249. break;
  250. pos.inTypename = 0;
  251. }
  252. if( !pos.inTypename && dat )
  253. {
  254. int anz = dat->klassen.getEintragAnzahl();
  255. for( int i = 0; i < anz; i++ )
  256. {
  257. int tl = dat->klassen.get( i )->name.getLength();
  258. pos.inTypename = 1;
  259. for( int j = 0; j < tl && j + pos.pos <= scriptL && pos.inTypename; j++ )
  260. pos.inTypename &= txt->getText()[ j + pos.pos - 1 ] == dat->klassen.get( i )->name.getText()[ j ];
  261. if( pos.inTypename && ( tl - 1 + pos.pos == scriptL || istTrenner( txt->getText()[ tl - 1 + pos.pos ] ) ) )
  262. break;
  263. pos.inTypename = 0;
  264. }
  265. }
  266. }
  267. if( !pos.inInstanzVar && !pos.inParameter && !pos.inKeyword && !pos.inTypename && pos.lastLehr )
  268. {
  269. for( auto i = abschnitt.getArray(); i.set; i++ )
  270. {
  271. if( i.var.anfang <= pos.pos - 1 && i.var.ende >= pos.pos - 1 )
  272. {
  273. if( i.var.zFunktion )
  274. {
  275. int anz = i.var.zFunktion->parameter.getEintragAnzahl();
  276. for( int j = 0; j < anz; j++ )
  277. {
  278. int nl = i.var.zFunktion->parameter.get( j )->name.getLength();
  279. pos.inParameter = 1;
  280. for( int k = 0; k < nl && k + pos.pos <= scriptL && pos.inParameter; k++ )
  281. pos.inParameter &= txt->getText()[ k + pos.pos - 1 ] == i.var.zFunktion->parameter.get( j )->name.getText()[ k ];
  282. if( pos.inParameter && ( nl - 1 + pos.pos == scriptL || istTrenner( txt->getText()[ nl - 1 + pos.pos ] ) ) )
  283. break;
  284. pos.inParameter = 0;
  285. }
  286. }
  287. }
  288. }
  289. }
  290. if( !pos.inInstanzVar && !pos.inParameter && !pos.inKeyword && !pos.inTypename && pos.lastLehr )
  291. {
  292. for( auto i = abschnitt.getArray(); i.set; i++ )
  293. {
  294. if( i.var.anfang <= pos.pos - 1 && i.var.ende >= pos.pos - 1 )
  295. {
  296. if( i.var.zKlasse )
  297. {
  298. int anz = i.var.zKlasse->variablen.getEintragAnzahl();
  299. for( int j = 0; j < anz; j++ )
  300. {
  301. int nl = i.var.zKlasse->variablen.get( j )->name.getLength();
  302. pos.inInstanzVar = 1;
  303. for( int k = 0; k < nl && k + pos.pos <= scriptL && pos.inInstanzVar; k++ )
  304. pos.inInstanzVar &= txt->getText()[ k + pos.pos - 1 ] == i.var.zKlasse->variablen.get( j )->name.getText()[ k ];
  305. if( pos.inInstanzVar && ( nl - 1 + pos.pos == scriptL || istTrenner( txt->getText()[ nl - 1 + pos.pos ] ) ) )
  306. break;
  307. pos.inInstanzVar = 0;
  308. }
  309. }
  310. }
  311. }
  312. }
  313. }
  314. if( pos.inKeyword )
  315. color = KSGScriptEditor::ColorType::KEYWORD;
  316. if( pos.inTypename )
  317. color = KSGScriptEditor::ColorType::TYPENAME;
  318. if( pos.inParameter )
  319. color = KSGScriptEditor::ColorType::PARAMETER_VARIABLE;
  320. if( pos.inInstanzVar )
  321. color = KSGScriptEditor::ColorType::INSTANCE_VARIABLE;
  322. if( pos.inChar || pos.inString || inString )
  323. color = KSGScriptEditor::ColorType::STRING;
  324. for( auto i = error.getArray(); i.set; i++ )
  325. {
  326. if( i.var.anfang <= pos.pos && i.var.ende >= pos.pos )
  327. underlineC = KSGScriptEditor::ColorType::ERROR_UNDERLINE;
  328. }
  329. pos.lastLehr = istLehr( c );
  330. pos.lastTrenner = istTrenner( c );
  331. return color;
  332. }
  333. // Reference Counting
  334. ColorParser *ColorParser::getThis()
  335. {
  336. ref++;
  337. return this;
  338. }
  339. ColorParser *ColorParser::release()
  340. {
  341. if( !--ref )
  342. delete this;
  343. return 0;
  344. }