ColorParser.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  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. : KSGSLeser()
  11. {
  12. txt = dynamic_cast<Text*>(zTxt->getThis());
  13. reset();
  14. reload();
  15. }
  16. // Destructor
  17. ColorParser::~ColorParser()
  18. {
  19. for( auto i : abschnitt )
  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 )
  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( dynamic_cast<Text*>(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( fileName );
  167. fileName.setText( dPf );
  168. Reader* tmp = d;
  169. if( !ladeDatei() )
  170. {
  171. handleError( (int)d->getLPosition() - 1, (int)d->getLPosition() );
  172. d = tmp;
  173. fileName.setText( pf );
  174. //error( 6, { "Lade Anweisung", *pfad }, zObj );
  175. br = 1;
  176. break;
  177. }
  178. d = tmp;
  179. fileName.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 = (Reader*)((TextReader*)d)->release();
  197. }
  198. KSGSLeseKlasse* ColorParser::leseKlasse()
  199. {
  200. Abschnitt abs;
  201. abs.anfang = (int)d->getLPosition();
  202. KSGSLeseKlasse* ret = KSGSLeser::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 = KSGSLeser::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 cm1 = txt->getText()[ p - 1 ];
  230. if( istLehr( cm1 ) || istTrenner( cm1 ) )
  231. {
  232. pos.inKeyword = 0;
  233. pos.inTypename = 0;
  234. pos.inInstanzVar = 0;
  235. pos.inParameter = 0;
  236. }
  237. bool inString = 0;
  238. bool inKommentar = 0;
  239. for( auto i : string )
  240. {
  241. if( i.anfang <= p && i.ende >= p )
  242. inString = 1;
  243. }
  244. for( auto i : kommentar )
  245. {
  246. if( i.anfang <= p && i.ende >= p )
  247. inKommentar = 1;
  248. }
  249. if( !inString && !inKommentar )
  250. {
  251. if( !pos.inInstanzVar && !pos.inParameter && !pos.inKeyword && !pos.inTypename && istLehr( cm1 ) )
  252. {
  253. for( int i = 0; i < keywordAnz; i++ )
  254. {
  255. int kl = textLength( keyword[ i ] );
  256. pos.inKeyword = 1;
  257. for( int j = 0; j < kl && j + p < scriptL && pos.inKeyword; j++ )
  258. pos.inKeyword &= txt->getText()[ j + p ] == keyword[ i ][ j ];
  259. if( pos.inKeyword && (kl + p == scriptL || istTrenner( txt->getText()[ kl + p ] )) )
  260. break;
  261. pos.inKeyword = 0;
  262. }
  263. }
  264. if( !pos.inInstanzVar && !pos.inParameter && !pos.inKeyword && !pos.inTypename && istLehr( cm1 ) )
  265. {
  266. for( int i = 0; i < typeAnz; i++ )
  267. {
  268. int tl = textLength( type[ i ] );
  269. pos.inTypename = 1;
  270. for( int j = 0; j < tl && j + p < scriptL && pos.inTypename; j++ )
  271. pos.inTypename &= txt->getText()[ j + p ] == type[ i ][ j ];
  272. if( pos.inTypename && (tl + p == scriptL || istTrenner( txt->getText()[ tl + p ] )) )
  273. break;
  274. pos.inTypename = 0;
  275. }
  276. if( !pos.inTypename && dat )
  277. {
  278. int anz = dat->klassen.getEintragAnzahl();
  279. for( int i = 0; i < anz; i++ )
  280. {
  281. int tl = dat->klassen.get( i )->name.getLength();
  282. pos.inTypename = 1;
  283. for( int j = 0; j < tl && j + p < scriptL && pos.inTypename; j++ )
  284. pos.inTypename &= txt->getText()[ j + p ] == dat->klassen.get( i )->name.getText()[ j ];
  285. if( pos.inTypename && (tl + p == scriptL || istTrenner( txt->getText()[ tl + p ] )) )
  286. break;
  287. pos.inTypename = 0;
  288. }
  289. }
  290. }
  291. if( !pos.inInstanzVar && !pos.inParameter && !pos.inKeyword && !pos.inTypename && istLehr( cm1 ) )
  292. {
  293. for( const Abschnitt& i : abschnitt )
  294. {
  295. if( i.anfang <= p && i.ende >= p )
  296. {
  297. if( i.zFunktion )
  298. {
  299. int anz = i.zFunktion->parameter.getEintragAnzahl();
  300. for( int j = 0; j < anz; j++ )
  301. {
  302. int nl = i.zFunktion->parameter.get( j )->name.getLength();
  303. pos.inParameter = 1;
  304. for( int k = 0; k < nl && k + p < scriptL && pos.inParameter; k++ )
  305. pos.inParameter &= txt->getText()[ k + p ] == i.zFunktion->parameter.get( j )->name.getText()[ k ];
  306. if( pos.inParameter && (nl + p == scriptL || istTrenner( txt->getText()[ nl + p ] )) )
  307. break;
  308. pos.inParameter = 0;
  309. }
  310. }
  311. }
  312. }
  313. }
  314. if( !pos.inInstanzVar && !pos.inParameter && !pos.inKeyword && !pos.inTypename && istLehr( cm1 ) )
  315. {
  316. for( const Abschnitt& i : abschnitt )
  317. {
  318. if( i.anfang <= p && i.ende >= p )
  319. {
  320. if( i.zKlasse )
  321. {
  322. int anz = i.zKlasse->variablen.getEintragAnzahl();
  323. for( int j = 0; j < anz; j++ )
  324. {
  325. int nl = i.zKlasse->variablen.get( j )->name.getLength();
  326. pos.inInstanzVar = 1;
  327. for( int k = 0; k < nl && k + p < scriptL && pos.inInstanzVar; k++ )
  328. pos.inInstanzVar &= txt->getText()[ k + p ] == i.zKlasse->variablen.get( j )->name.getText()[ k ];
  329. if( pos.inInstanzVar && (nl + p == scriptL || istTrenner( txt->getText()[ nl + p ] )) )
  330. break;
  331. pos.inInstanzVar = 0;
  332. }
  333. }
  334. }
  335. }
  336. }
  337. }
  338. if( pos.inKeyword )
  339. color = KSGScriptEditor::ColorType::KEYWORD;
  340. if( pos.inTypename )
  341. color = KSGScriptEditor::ColorType::TYPENAME;
  342. if( pos.inParameter )
  343. color = KSGScriptEditor::ColorType::PARAMETER_VARIABLE;
  344. if( pos.inInstanzVar )
  345. color = KSGScriptEditor::ColorType::INSTANCE_VARIABLE;
  346. if( inString )
  347. color = KSGScriptEditor::ColorType::STRING;
  348. if( inKommentar )
  349. color = KSGScriptEditor::ColorType::KOMMENTAR;
  350. for( auto i : error )
  351. {
  352. if( i.anfang <= p && i.ende >= p )
  353. underlineC = (int)KSGScriptEditor::ColorType::ERROR_UNDERLINE;
  354. }
  355. return color;
  356. }