ColorParser.cpp 12 KB

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