ColorParser.cpp 12 KB

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