PageRenderTime 49ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/source/src/System/Language/mathemagix_language.cpp

http://itexmacs.googlecode.com/
C++ | 762 lines | 716 code | 36 blank | 10 comment | 241 complexity | 884a9a332fba3ddc239b2931c45350b5 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, MPL-2.0-no-copyleft-exception, LGPL-2.0
  1. /******************************************************************************
  2. * MODULE : mathemagix_language.cpp
  3. * DESCRIPTION: the "mathemagix" language
  4. * COPYRIGHT : (C) 2008 Francis Jamet
  5. *******************************************************************************
  6. * This software falls under the GNU general public license version 3 or later.
  7. * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
  8. * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
  9. ******************************************************************************/
  10. #include "analyze.hpp"
  11. #include "impl_language.hpp"
  12. #include "Scheme/object.hpp"
  13. #define COLOR_MARKUP "#500d04"
  14. static void parse_number (string s, int& pos);
  15. static void parse_string (string s, int& pos);
  16. static void parse_alpha (string s, int& pos);
  17. mathemagix_language_rep::mathemagix_language_rep (string name):
  18. language_rep (name), colored ("")
  19. {
  20. eval ("(use-modules (utils misc tm-keywords))");
  21. list<string> l= as_list_string (eval ("(map symbol->string highlight-any)"));
  22. while (!is_nil (l)) {
  23. colored (l->item)= "blue";
  24. l= l->next;
  25. }
  26. }
  27. text_property
  28. mathemagix_language_rep::advance (tree t, int& pos) {
  29. string s= t->label;
  30. if (pos==N(s)) return &tp_normal_rep;
  31. char c= s[pos];
  32. if (c == ' ') {
  33. pos++; return &tp_space_rep; }
  34. if (c >= '0' && c <= '9') {
  35. parse_number (s, pos); return &tp_normal_rep; }
  36. if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
  37. (c == '_') || (c == '$')) {
  38. parse_alpha (s, pos); return &tp_normal_rep; }
  39. tm_char_forwards (s, pos);
  40. return &tp_normal_rep;
  41. }
  42. array<int>
  43. mathemagix_language_rep::get_hyphens (string s) {
  44. int i;
  45. array<int> penalty (N(s)+1);
  46. penalty[0]= HYPH_INVALID;
  47. for (i=1; i<N(s); i++)
  48. if (s[i-1] == '-' && is_alpha (s[i]))
  49. penalty[i]= HYPH_STD;
  50. else penalty[i]= HYPH_INVALID;
  51. penalty[i]= HYPH_INVALID;
  52. return penalty;
  53. }
  54. void
  55. mathemagix_language_rep::hyphenate (
  56. string s, int after, string& left, string& right)
  57. {
  58. left = s(0, after);
  59. right= s(after, N(s));
  60. }
  61. static void
  62. mathemagix_color_setup_constants (hashmap<string, string> & t) {
  63. string c= "#2060c0";
  64. t ("cpp_flags")= c;
  65. t ("cpp_libs")= c;
  66. t ("cpp_preamble")= c;
  67. t ("cpp_macro")= c;
  68. t ("cpp_include")= c;
  69. t ("true")= c;
  70. t ("false")= c;
  71. t ("mmout")= c;
  72. t ("mmin")= c;
  73. t ("mmerr")= c;
  74. t ("blank")= c;
  75. t ("stroke")= c;
  76. t ("indent")= c;
  77. t ("unindent")= c;
  78. t ("lf")= c;
  79. t ("hrule")= c;
  80. t ("flush_now")= c;
  81. t ("nil")= c;
  82. }
  83. static void
  84. mathemagix_color_setup_keywords (hashmap<string, string> & t) {
  85. string c= "#8020c0"; string d= "modifier"; string e= "class";
  86. t ("abstract")= c;
  87. t ("alias")= c;
  88. t ("and")= c;
  89. t ("assume")= d;
  90. t ("begin")= c;
  91. t ("break")= c;
  92. t ("case")= c;
  93. t ("cast")= c;
  94. t ("catch")= c;
  95. t ("category")= e;
  96. t ("class")= e;
  97. t ("concrete")= c;
  98. t ("constant")= c;
  99. t ("constructor")= c;
  100. t ("continue")= c;
  101. t ("convert")= c;
  102. t ("debugger")= c;
  103. t ("destructor")= c;
  104. t ("direct")= c;
  105. t ("div")= c;
  106. t ("do")= c;
  107. t ("downto")= c;
  108. t ("downgrade")= c;
  109. t ("else")= c;
  110. t ("evolutive")= c;
  111. t ("exists")= d;
  112. t ("explode")= c;
  113. t ("export")= d;
  114. t ("extend")= c;
  115. t ("extern")= c;
  116. t ("for")= c;
  117. t ("forall")= d;
  118. t ("foreach")= c;
  119. t ("foreign")= c;
  120. t ("from")= c;
  121. t ("fuse")= c;
  122. t ("generate")= c;
  123. t ("has")= c;
  124. t ("help")= c;
  125. t ("hidden")= c;
  126. t ("holds")= c;
  127. t ("if")= c;
  128. t ("import")= c;
  129. t ("in")= c;
  130. t ("include")= c;
  131. t ("indirect")= c;
  132. t ("infix")= c;
  133. t ("inherit")= c;
  134. t ("inline")= d;
  135. t ("inplace")= c;
  136. t ("interactive")= c;
  137. t ("intern")= c;
  138. t ("join")= c;
  139. t ("keyword")= c;
  140. t ("literal")= c;
  141. t ("lambda")= c;
  142. t ("literal_integer")= c;
  143. t ("literal_floating")= c;
  144. t ("literal_string")= c;
  145. t ("locked")= c;
  146. t ("loop")= c;
  147. t ("macro")= c;
  148. t ("map")= c;
  149. t ("melt")= c;
  150. t ("method")= c;
  151. t ("mod")= c;
  152. t ("module")= e;
  153. t ("mutable")= c;
  154. t ("operator")= c;
  155. t ("or")= c;
  156. t ("packed")= c;
  157. t ("penalty")= c;
  158. t ("postfix")= "postfix";
  159. t ("prefix")= c;
  160. t ("private")= c;
  161. t ("protected")= c;
  162. t ("public")= c;
  163. t ("outline")= c;
  164. t ("quit")= c;
  165. t ("quo")= c;
  166. t ("raise")= c;
  167. t ("rem")= c ;
  168. t ("require")= c;
  169. t ("return")= c ;
  170. t ("sequel")= c;
  171. t ("split")= c;
  172. t ("step")= c;
  173. t ("supports?")= c;
  174. t ("then")= c;
  175. t ("this")= c;
  176. t ("to")= c;
  177. t ("try")= c;
  178. t ("type")= c;
  179. t ("unpacked")= c;
  180. t ("until")= c;
  181. t ("upgrade")= c;
  182. t ("use")= c;
  183. t ("value")= c;
  184. t ("while")= c;
  185. t ("with")= c;
  186. t ("xor")= c;
  187. }
  188. static void
  189. mathemagix_color_setup_otherlexeme (hashmap<string, string>& t) {
  190. string c= "black";
  191. t ("==<gtr>")= c;
  192. t ("==")= c;
  193. t (":=")= c;
  194. t ("+=")= c;
  195. t ("-=")= c;
  196. t ("*=")= c;
  197. t ("/=")= c;
  198. t (":=<gtr>")= c;
  199. t (":-<gtr>")= c;
  200. t ("yield")= c;
  201. t (",")= c;
  202. t (";")= c;
  203. t (")")= c;
  204. t ("[")= c;
  205. t ("]")= c;
  206. t ("{")= c;
  207. t ("}")= c;
  208. t ("<less><less>")= c;
  209. t ("<less><less>*")= c;
  210. t ("<less><less>%")= c;
  211. t ("<gtr><gtr>")= c;
  212. t ("|")= c;
  213. }
  214. static inline bool
  215. belongs_to_identifier (char c) {
  216. return ((c<='9' && c>='0') ||
  217. (c<='Z' && c>='A') ||
  218. (c<='z' && c>='a') ||
  219. c=='_' || c=='$' || c=='?');
  220. }
  221. static inline bool
  222. is_number (char c) {
  223. return (c>='0' && c<='9');
  224. }
  225. static void
  226. parse_identifier (hashmap<string, string>& t,
  227. string s, int& pos, bool postfix) {
  228. int i=pos;
  229. if (pos>=N(s)) return;
  230. if (is_number (s[i])) return;
  231. if (postfix && s[i]=='.') i++;
  232. while (i<N(s) && belongs_to_identifier (s[i])) i++;
  233. if (!(t->contains (s (pos, i)))) pos= i;
  234. }
  235. static void
  236. parse_identifier_or_markup (hashmap<string, string>& t,
  237. string s, int& pos, bool postfix, bool& is_markup) {
  238. int i=pos;
  239. is_markup= false;
  240. if (pos>=N(s)) return;
  241. if (is_number (s[i])) return;
  242. if (postfix && s[i]=='.') i++;
  243. while (i<N(s) && belongs_to_identifier (s[i])) {
  244. if (s[i]=='$') is_markup= true;
  245. i++;
  246. }
  247. if (!(t->contains (s (pos, i)))) pos= i;
  248. }
  249. static void
  250. parse_alpha (string s, int& pos) {
  251. static hashmap<string,string> empty;
  252. parse_identifier (empty, s, pos, false);
  253. }
  254. static void
  255. parse_blanks (string s, int& pos) {
  256. while (pos<N(s) && (s[pos]==' ' || s[pos]=='\t')) pos++;
  257. }
  258. static void
  259. parse_string (string s, int& pos) {
  260. if (pos>=N(s)) return;
  261. switch (s[pos]) {
  262. case '\042':
  263. do pos++;
  264. while((pos<N(s)) &&
  265. ((s[pos-1]=='\\' && s[pos]=='\042') || s[pos]!='\042'));
  266. if (s[pos]=='\042') pos++;
  267. return;
  268. case '/':
  269. if (pos+1<N(s) && s[pos+1]=='\042') {
  270. pos=pos+2;
  271. do {
  272. if (pos+1<N(s) && s[pos]=='\042' && s[pos+1]=='/') {
  273. pos=pos+2; return; }
  274. pos++;
  275. } while (pos<N(s));
  276. }
  277. }
  278. }
  279. static void
  280. parse_keyword (hashmap<string,string>& t, string s, int& pos) {
  281. int i= pos;
  282. if (pos>=N(s)) return;
  283. if (is_number (s[i])) return;
  284. while ((i<N(s)) && belongs_to_identifier (s[i])) i++;
  285. string r= s (pos, i);
  286. if (t->contains (r) && t(r)=="#8020c0") { pos=i; return; }
  287. }
  288. static void
  289. parse_modifier (hashmap<string,string>& t, string s, int& pos) {
  290. int i= pos;
  291. if (pos>=N(s)) return;
  292. if (is_number (s[i])) return;
  293. while ((i<N(s)) && belongs_to_identifier (s[i])) i++;
  294. string r= s (pos, i);
  295. if (t->contains (r) && t(r)=="modifier") { pos=i; return; }
  296. }
  297. static void
  298. parse_class (hashmap<string,string>& t, string s, int& pos) {
  299. int i= pos;
  300. if (pos>=N(s)) return;
  301. if (is_number (s[i])) return;
  302. while ((i<N(s)) && belongs_to_identifier (s[i])) i++;
  303. string r= s (pos, i);
  304. if (t->contains (r) && t(r)=="class") { pos=i; return; }
  305. }
  306. static void
  307. parse_postfix (hashmap<string,string>& t, string s, int& pos) {
  308. int i= pos;
  309. if (pos>=N(s)) return;
  310. if (is_number (s[i])) return;
  311. while ((i<N(s)) && belongs_to_identifier (s[i])) i++;
  312. string r= s (pos, i);
  313. if (t->contains (r) && t(r)=="postfix") { pos=i; return; }
  314. }
  315. static void
  316. parse_constant (hashmap<string,string>& t, string s, int& pos) {
  317. int i=pos;
  318. if (pos>=N(s)) return;
  319. if (is_number (s[i])) return;
  320. while ((i<N(s)) && belongs_to_identifier (s[i])) i++;
  321. string r= s (pos, i);
  322. if (t->contains (r) && t(r)=="#2060c0") { pos=i; return; }
  323. }
  324. static void
  325. parse_other_lexeme (hashmap<string,string>& t, string s, int& pos) {
  326. int i;
  327. for (i=12; i>=1; i--) {
  328. string r=s(pos,pos+i);
  329. if (t->contains(r) && t(r)=="black") {
  330. pos=pos+i; return; }
  331. }
  332. }
  333. static void
  334. parse_number (string s, int& pos) {
  335. int i= pos;
  336. if (pos>=N(s)) return;
  337. if (s[i] == '.') return;
  338. while (i<N(s) &&
  339. (is_number (s[i]) ||
  340. (s[i] == '.' && (i+1<N(s)) &&
  341. (is_number (s[i+1]) ||
  342. s[i+1] == 'e' || s[i+1] == 'E')))) i++;
  343. if (i == pos) return;
  344. if (i<N(s) && (s[i] == 'e' || s[i] == 'E')) {
  345. i++;
  346. if (i<N(s) && s[i] == '-') i++;
  347. while (i<N(s) && (is_number (s[i]))) i++;
  348. }
  349. pos= i;
  350. }
  351. static void
  352. parse_no_declare_type (string s, int& pos) {
  353. if (pos+1<N(s) && s[pos]==':' && s[pos+1]==':') pos=pos+2;
  354. }
  355. static void
  356. parse_declare_type (string s, int& pos) {
  357. if (pos>=N(s)) return;
  358. if (s[pos]!=':') return;
  359. if (pos+1<N(s) && s[pos+1]=='=') return;
  360. pos++;
  361. if (!test (s, pos, "<gtr>")) return;
  362. pos+=5;
  363. }
  364. static void
  365. parse_comment (string s, int& pos) {
  366. if (pos>=N(s)) return;
  367. if (s[pos]!='/') return;
  368. if (pos+1<N(s) && s[pos+1]=='/') {pos=N(s);return;}
  369. if (pos+1<N(s) && s[pos+1]=='{') {
  370. pos= pos+2;
  371. while ((pos<N(s) && s[pos]!='}') || (pos+1<N(s) && s[pos+1]!='/')) pos++;
  372. pos= min(pos+2,N(s));
  373. }
  374. }
  375. static void
  376. parse_end_comment (string s, int& pos) {
  377. if (pos+1<N(s) && s[pos]=='}' && s[pos+1]=='/') pos=pos+2;
  378. }
  379. static void
  380. parse_parenthesized (string s, int& pos) {
  381. int i=pos;
  382. if (pos>=N(s)) return;
  383. if (s[i]!='(') return;
  384. int nbpar=0;
  385. while(i<N(s)) {
  386. switch (s[i]) {
  387. case '(':
  388. nbpar++;break;
  389. case ')':if (nbpar>0) nbpar--;
  390. if (nbpar==0) {i++;pos=i;return;}
  391. break;
  392. case '/':
  393. if (i+1<N(s) &&
  394. (s[i+1]=='\042' || s[i+1]=='{' || s[i+1]=='/')) {
  395. pos= i; return; }
  396. break;
  397. case '\042':
  398. pos=i;
  399. return;
  400. }
  401. i++;
  402. }
  403. pos=i;
  404. }
  405. static void
  406. parse_backquote (string s, int & pos) {
  407. if (pos>=N(s)) return;
  408. if (s[pos]=='\047') pos++;
  409. }
  410. static void
  411. parse_declare_function (string s, int& pos) {
  412. if (pos+1>=N(s)) return;
  413. if (s[pos]==':' && s[pos+1]=='=') { pos=pos+2; return; }
  414. if (s[pos]=='=' && s[pos+1]=='=') { pos=pos+2; return; }
  415. }
  416. static void
  417. parse_declare_macro (string s, int& pos) {
  418. if (test(s,pos,"==<gtr>")) { pos=pos+7; return; }
  419. if (test(s,pos,":=<gtr>")) { pos=pos+7; return; }
  420. }
  421. string
  422. mathemagix_language_rep::get_color (tree t, int start, int end) {
  423. static bool setup_done= false;
  424. if (!setup_done) {
  425. mathemagix_color_setup_constants (colored);
  426. mathemagix_color_setup_keywords (colored);
  427. mathemagix_color_setup_otherlexeme (colored);
  428. setup_done= true;
  429. }
  430. static string none= "";
  431. if (start >= end) return none;
  432. string s= t->label;
  433. int pos=0;int opos;
  434. bool backquote= false;
  435. bool after_backquote;
  436. bool postfix= false;
  437. bool possible_function= true;
  438. bool possible_type= false;
  439. bool possible_class= false;
  440. bool possible_future_type= false;
  441. bool possible_future_function= true;
  442. bool possible_future_class= false;
  443. string type;
  444. bool is_markup;
  445. do {
  446. do {
  447. opos=pos;
  448. parse_string (s, pos);
  449. if (opos<pos) break;
  450. parse_comment (s, pos);
  451. if (opos<pos) break;
  452. parse_end_comment (s, pos);
  453. if (opos<pos) {
  454. if (pos>start) {return "brown";}
  455. else break;
  456. }
  457. pos++;
  458. }
  459. while(false);
  460. }
  461. while(pos<N(s));
  462. pos=0;
  463. do {
  464. type= none;
  465. do {
  466. after_backquote= backquote;
  467. possible_function= possible_future_function;
  468. possible_type= possible_future_type;
  469. possible_class= possible_future_class;
  470. opos= pos;
  471. parse_blanks (s, pos);
  472. if (opos<pos) break;
  473. parse_string (s, pos);
  474. if (opos<pos) {
  475. type= "string";
  476. backquote= false;
  477. postfix= false;
  478. possible_future_function= false;
  479. possible_future_type= false;
  480. possible_future_class= false;
  481. possible_type= false;
  482. break;
  483. }
  484. parse_comment (s, pos);
  485. if (opos<pos) {
  486. type= "comment";
  487. backquote= false;
  488. postfix= false;
  489. possible_future_type= false;
  490. possible_type= false;
  491. break;
  492. }
  493. parse_modifier (colored, s, pos);
  494. if (opos<pos) {
  495. type="keyword";
  496. backquote= false;
  497. postfix= false;
  498. possible_future_type= false;
  499. possible_type= false;
  500. possible_function= false;
  501. break;
  502. }
  503. parse_postfix (colored, s, pos);
  504. if (opos<pos) {
  505. type="keyword";
  506. backquote= false;
  507. postfix= true;
  508. possible_future_type= false;
  509. possible_future_class= false;
  510. possible_type= false;
  511. possible_function= false;
  512. possible_future_class= false;
  513. break;
  514. }
  515. parse_class (colored, s, pos);
  516. if (opos<pos) {
  517. type= "keyword";
  518. backquote=false;
  519. postfix=false;
  520. possible_future_type= false;
  521. possible_type= false;
  522. possible_future_class=true;
  523. possible_future_function= false;
  524. break;
  525. }
  526. parse_keyword (colored, s, pos);
  527. if (opos<pos) {
  528. type= "keyword";
  529. backquote= false;
  530. postfix= false;
  531. possible_future_type= false;
  532. possible_type= false;
  533. possible_function= false;
  534. possible_future_function= false;
  535. possible_future_class= false;
  536. break;
  537. }
  538. parse_other_lexeme (colored, s, pos); //not left parenthesis
  539. if (opos<pos) {
  540. type= "other_lexeme";
  541. backquote= false;
  542. postfix= false;
  543. possible_function= false;
  544. possible_future_function= true;
  545. possible_future_type= false;
  546. possible_future_class= false;
  547. possible_type= false;
  548. break;
  549. }
  550. parse_constant (colored, s, pos);
  551. if (opos<pos) {
  552. type= "constant";
  553. backquote= false;
  554. postfix= false;
  555. possible_future_function= false;
  556. possible_future_class= false;
  557. break;
  558. }
  559. parse_number (s, pos);
  560. if (opos<pos) {
  561. type= "number";
  562. backquote= false;
  563. postfix= false;
  564. possible_future_function= false;
  565. possible_future_class= false;
  566. break;
  567. }
  568. parse_no_declare_type (s, pos); // ::
  569. if (opos<pos) {
  570. type= "no_declare_type";
  571. possible_type= false;
  572. possible_future_type= false;
  573. possible_function= false;
  574. possible_future_function= false;
  575. possible_future_class= false;
  576. break;
  577. }
  578. parse_backquote (s, pos);
  579. if (opos<pos) {
  580. backquote= true;
  581. postfix= false;
  582. possible_future_function= false;
  583. possible_future_class= false;
  584. break;
  585. }
  586. parse_declare_type (s, pos); // : and :>
  587. if (opos<pos) {
  588. type= "declare_type";
  589. backquote= false;
  590. postfix= false;
  591. if (!after_backquote) possible_future_type=true;
  592. possible_function= false;
  593. possible_future_function= false;
  594. possible_future_class= false;
  595. break;
  596. }
  597. parse_identifier_or_markup (colored, s, pos, postfix, is_markup);
  598. if (opos<pos) {
  599. if (is_markup) {type= "identifier_markup";} else type= "identifier";
  600. backquote= false;
  601. postfix= false;
  602. possible_future_function=false;
  603. possible_future_class= false;
  604. break;
  605. }
  606. parse_parenthesized (s, pos);
  607. // stops after well parenthesized ) or before // or /{ or " or /"
  608. if (opos<pos && pos<=start) {
  609. type="left_parenthesis";
  610. backquote= false;
  611. postfix= false;
  612. possible_function= false;
  613. possible_future_function= true;
  614. possible_future_class= false;
  615. break;
  616. }
  617. if (opos<pos && possible_type==true)
  618. return "dark green";
  619. if (opos<pos && after_backquote)
  620. return none;
  621. backquote= false;
  622. postfix= false;
  623. pos= opos;
  624. pos++;
  625. }
  626. while (false);
  627. }
  628. while (pos<=start);
  629. if (possible_type) return "dark green";
  630. if (type=="string") return "#a06040";
  631. if (type=="comment") return "brown";
  632. if (type=="keyword" && !after_backquote) return "#8020c0";
  633. if (type=="other_lexeme") return none;
  634. if (type=="constant") return "#2060c0";
  635. if (type=="number") return "#2060c0";
  636. if (type=="no_declare_type") return none;
  637. if (type=="declare_type") return none;
  638. if (type=="left_parenthesis") return none;
  639. if (type=="identifier" && possible_function==false && possible_class==false)
  640. return none;
  641. if (type=="identifier_markup" && possible_function==false
  642. && possible_class==false)
  643. return COLOR_MARKUP;
  644. if ( (type=="identifier" || type=="identifier_markup") && possible_function) {
  645. possible_function= false;
  646. do {
  647. do {
  648. opos=pos;
  649. parse_blanks (s, pos);
  650. if (opos<pos) break;
  651. parse_identifier (colored, s, pos,false);
  652. if (opos<pos) { possible_function= true; break; }
  653. parse_number (s, pos);
  654. if (opos<pos) { possible_function= true; break; }
  655. parse_constant (colored, s, pos);
  656. if (opos<pos) { possible_function= true; break; }
  657. parse_comment (s, pos);
  658. if (opos<pos) break;
  659. parse_parenthesized (s, pos);
  660. if (opos<pos) { possible_function= true; break; }
  661. }
  662. while (false);
  663. }
  664. while (opos!=pos);
  665. if (!possible_function) {
  666. if (type=="identifier") {return none;} else return COLOR_MARKUP;
  667. }
  668. do {
  669. do {
  670. opos=pos;
  671. parse_blanks (s, pos);
  672. if (opos<pos) break;
  673. parse_identifier (colored, s, pos,false);
  674. if (opos<pos) break;
  675. parse_number(s,pos);
  676. if (opos<pos) break;
  677. parse_constant (colored, s, pos);
  678. if (opos<pos) break;
  679. parse_comment(s,pos);
  680. if (opos<pos) break;
  681. parse_parenthesized (s, pos);
  682. if (opos<pos) break;
  683. parse_no_declare_type (s, pos);
  684. if (opos<pos) break;
  685. parse_declare_type (s, pos);
  686. if (opos<pos) break;
  687. parse_declare_macro(s,pos);
  688. if (opos<pos) return "#00d000";
  689. parse_declare_function (s, pos);
  690. if (opos<pos) return "#0000e0";
  691. if (type=="identifier") {return none;} else return COLOR_MARKUP;
  692. }
  693. while (false);
  694. }
  695. while (pos<N(s));
  696. }
  697. if ( (type=="identifier" || type=="identifier_markup") && possible_class) {
  698. do {
  699. do {
  700. opos=pos;
  701. parse_blanks (s, pos);
  702. if (opos<pos) break;
  703. parse_identifier (colored, s, pos,false);
  704. if (opos<pos) break;
  705. parse_number(s,pos);
  706. if (opos<pos) break;
  707. parse_constant (colored, s, pos);
  708. if (opos<pos) break;
  709. parse_comment(s,pos);
  710. if (opos<pos) break;
  711. parse_parenthesized (s, pos);
  712. if (opos<pos) break;
  713. parse_no_declare_type (s, pos);
  714. if (opos<pos) break;
  715. parse_declare_type (s, pos);
  716. if (opos<pos) break;
  717. parse_declare_function (s, pos);
  718. if (opos<pos) return "#0000e0";
  719. if (type=="identifier") {return none;} else return COLOR_MARKUP;
  720. }
  721. while (false);
  722. }
  723. while (pos<N(s));
  724. }
  725. if (type=="identifier_markup") {return COLOR_MARKUP;} else return none;
  726. }