syntax.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. #include "__virtualmath.h"
  2. /**
  3. * 匹配一个数字字面量
  4. * 匹配器规则:
  5. * START模式:判断比较第一个字符(是否为数字或者小数点),若匹配成功则进入ING模式,若失败则进入MISTAKE模式
  6. * ING模式:继续匹配,直到遇到非数字或小数点。则检查是否为英文字母,若是则进入SECOND模式,否则进入END模式
  7. * SECOND模式:继续匹配,知道遇到非字母、下划线、数字的内容,进入END模式
  8. * END模式:进入END模式意味着匹配结束了,通过checkoutMather可以检查该匹配器是否被采用,采用后则生成token,并且读取器回退一个字符
  9. * MISTAKE模式:错误
  10. * 匹配内容:12.3jk_2,其中12.3存储在str中,jk_2存储在str_second中
  11. * @param p
  12. * @param mather
  13. */
  14. void numberMather(wint_t p, LexMather *mather){
  15. if (mather->status == LEXMATHER_START || mather->status == LEXMATHER_ING_1 || mather->status == LEXMATHER_ING_2)
  16. if (iswdigit(p) || L'.' == p && mather->status == LEXMATHER_ING_1){ // LEXMATHER_ING_1: 整数匹配
  17. mather->str = memWideCharcpy(mather->str, 1, true, true, p);
  18. mather->len += 1;
  19. if (L'.' == p)
  20. mather->status = LEXMATHER_ING_2;
  21. else if (mather->status == LEXMATHER_START)
  22. mather->status = LEXMATHER_ING_1;
  23. }
  24. else if(mather->status == LEXMATHER_ING_1 || mather->status == LEXMATHER_ING_2){ // LEXMATHER_ING_2: 小数匹配
  25. if (iswalpha(p) || L'_' == p){
  26. mather->second_str = memWideCharcpy(mather->second_str, 1, true, true, p);
  27. mather->status = LEXMATHER_ING_3;
  28. }
  29. else
  30. mather->status = LEXMATHER_END_1;
  31. }
  32. else
  33. mather->status = LEXMATHER_MISTAKE;
  34. else if (mather->status == LEXMATHER_ING_3)
  35. if (iswalnum(p) || L'_' == p)
  36. mather->second_str = memWideCharcpy(mather->second_str, 1, true, true, p);
  37. else
  38. mather->status = LEXMATHER_END_1;
  39. else
  40. mather->status = LEXMATHER_MISTAKE;
  41. }
  42. /**
  43. * 匹配一个变量
  44. * 匹配模式:匹配器结束模式为END_SECOND模式,也就是当checkoutMather检查的时候,END_SECOND位于END的优先级之后。
  45. * END_SECOND解决了冲突:关键词if可以满足varMather的匹配,但他并不是变量,if有特殊的匹配器(strMather)来匹配。
  46. * 匹配内容:a, a_123
  47. * @param p
  48. * @param mather
  49. */
  50. void varMather(wint_t p, LexMather *mather){
  51. if (mather->status == LEXMATHER_START || mather->status == LEXMATHER_ING_1){
  52. if (iswalpha(p) || L'_' == p || iswdigit(p) && mather->status == LEXMATHER_ING_1){
  53. mather->str = memWideCharcpy(mather->str, 1, true, true, p);
  54. mather->len ++;
  55. mather->status = LEXMATHER_ING_1;
  56. }
  57. else if(mather->status == LEXMATHER_ING_1)
  58. mather->status = LEXMATHER_END_2;
  59. else if(mather->status == LEXMATHER_START)
  60. mather->status = LEXMATHER_MISTAKE;
  61. }
  62. else
  63. mather->status = LEXMATHER_MISTAKE;
  64. }
  65. /**
  66. * 匹配一个字符串字面量
  67. * 注意:string_type记录的是字符串结束标志(‘或者“)
  68. * 此处引进LEXMATHER_PASS,是为了在匹配到结束标志"或者'后,多读取一个字符,然后在统一回退
  69. * 匹配内容:’134‘,”123“
  70. * @param p
  71. * @param mather
  72. */
  73. void stringMather(wint_t p, LexMather *mather, LexFile *file){
  74. if (mather->status == LEXMATHER_START)
  75. if (L'\"' == p || L'\'' == p){
  76. mather->status = LEXMATHER_ING_1;
  77. mather->string_type = p;
  78. }
  79. else
  80. mather->status = LEXMATHER_MISTAKE;
  81. else if (mather->status == LEXMATHER_ING_1)
  82. if (mather->string_type == p)
  83. mather->status = LEXMATHER_ING_4;
  84. else if (L'\\' == p)
  85. mather->status = LEXMATHER_ING_5;
  86. else if (WEOF == p) {
  87. file->errsyntax = L"stringMather: don't get quotation marks at the end of string";
  88. mather->status = LEXMATHER_MISTAKE;
  89. } else{
  90. mather->str = memWideCharcpy(mather->str, 1, true, true, p);
  91. mather->len ++;
  92. mather->status = LEXMATHER_ING_1;
  93. }
  94. else if (mather->status == LEXMATHER_ING_3)
  95. if (iswalnum(p) || L'_' == p)
  96. mather->second_str = memWideCharcpy(mather->second_str, 1, true, true, p);
  97. else
  98. mather->status = LEXMATHER_END_1;
  99. else if(mather->status == LEXMATHER_ING_4)
  100. if (iswalpha(p) || L'_' == p){
  101. mather->second_str = memWideCharcpy(mather->second_str, 1, true, true, p);
  102. mather->status = LEXMATHER_ING_3;
  103. }
  104. else
  105. mather->status = LEXMATHER_END_1;
  106. else if (mather->status == LEXMATHER_ING_5){
  107. wint_t new = WEOF;
  108. if (mather->string_type == '\'') {
  109. switch (p) {
  110. case L'n':
  111. new = L'\n';
  112. break;
  113. case L't':
  114. new = L'\t';
  115. break;
  116. case L'b':
  117. new = L'\b';
  118. break;
  119. case L'a':
  120. new = L'\a';
  121. break;
  122. case L'r':
  123. new = L'\r';
  124. break;
  125. case L'\'':
  126. new = L'\'';
  127. break;
  128. case L'"':
  129. new = L'"';
  130. break;
  131. case L'\\':
  132. new = L'\\';
  133. break;
  134. case L'[':
  135. mather->status = LEXMATHER_ING_6;
  136. break;
  137. default :
  138. case L'0':
  139. file->errsyntax = L"stringMather: don't support \\0";
  140. mather->status = LEXMATHER_MISTAKE;
  141. break;
  142. }
  143. if (new != WEOF) {
  144. mather->str = memWideCharcpy(mather->str, 1, true, true, new);
  145. mather->status = LEXMATHER_ING_1;
  146. mather->len++;
  147. }
  148. } else { // 双引号为无转义字符串 (只转义双引号)
  149. if (p != '"') {
  150. mather->str = memWideCharcpy(mather->str, 1, true, true, '\\');
  151. mather->len++;
  152. }
  153. mather->str = memWideCharcpy(mather->str, 1, true, true, p);
  154. mather->len++;
  155. mather->status = LEXMATHER_ING_1;
  156. }
  157. }
  158. else if (mather->status == LEXMATHER_ING_6)
  159. if (p == L']')
  160. if (mather->ascii <= 0) {
  161. mather->status = LEXMATHER_MISTAKE;
  162. file->errsyntax = L"stringMather: error ascii <= 0";
  163. } else {
  164. mather->str = memWideCharcpy(mather->str, 1, true, true, (char)mather->ascii);
  165. mather->status = LEXMATHER_ING_1;
  166. mather->len ++;
  167. }
  168. else if (iswdigit(p)){ // 手动输入ascii码
  169. wchar_t num_[2] = {(wchar_t)p, 0};
  170. int num = (int)wcstol(num_, NULL, 10); // ascii不大于127, 使用int即可
  171. mather->ascii = (mather->ascii * 10) + num;
  172. if (mather->ascii > 127) {
  173. file->errsyntax = L"stringMather: error ascii > 127";
  174. mather->status = LEXMATHER_MISTAKE;
  175. }
  176. } else {
  177. mather->status = LEXMATHER_MISTAKE;
  178. file->errsyntax = L"stringMather: no support from ascii";
  179. }
  180. else
  181. mather->status = LEXMATHER_MISTAKE;
  182. }
  183. /**
  184. * 匹配关键词dest_p
  185. * @param p
  186. * @param mather
  187. * @param dest_p
  188. */
  189. void strMather(wint_t p, LexMather *mather, const wchar_t *dest_p){
  190. if (mather->status == LEXMATHER_START || mather->status == LEXMATHER_ING_1)
  191. if (p == dest_p[mather->len]){
  192. mather->str = memWideCharcpy(mather->str, 1, true, true, p);
  193. mather->len ++;
  194. mather->status = LEXMATHER_ING_1;
  195. }
  196. else if(mather->status == LEXMATHER_ING_1 && mather->len == memWidelen(dest_p))
  197. mather->status = LEXMATHER_END_1;
  198. else
  199. mather->status = LEXMATHER_MISTAKE;
  200. else
  201. mather->status = LEXMATHER_MISTAKE;
  202. }
  203. /**
  204. * 匹配但个字符dest_p
  205. * @param p
  206. * @param mather
  207. * @param dest_p
  208. */
  209. void charMather(wint_t p, LexMather *mather, wint_t dest_p){
  210. if (p == dest_p && mather->status == LEXMATHER_START){
  211. mather->str = memWideCharcpy(mather->str, 1, true, true, p);
  212. mather->len ++;
  213. mather->status = LEXMATHER_ING_1;
  214. }
  215. else if (mather->status == LEXMATHER_ING_1)
  216. mather->status = LEXMATHER_END_1;
  217. else
  218. mather->status = LEXMATHER_MISTAKE;
  219. }
  220. void aCharMather(wint_t p, LexMather *mather, wint_t dest_p) {
  221. if (p == dest_p && mather->status == LEXMATHER_START){
  222. mather->str = memWideCharcpy(mather->str, 1, true, true, p);
  223. mather->len ++;
  224. mather->status = LEXMATHER_END_1;
  225. }
  226. else
  227. mather->status = LEXMATHER_MISTAKE;
  228. }
  229. /**
  230. * 匹配空白符号
  231. * @param p
  232. * @param mather
  233. */
  234. void spaceMather(wint_t p, LexMather *mather){
  235. if (mather->status == LEXMATHER_START || mather->status == LEXMATHER_ING_1)
  236. if (iswspace(p) && L'\n' != p){
  237. mather->str = memWideCharcpy(mather->str, 1, true, true, p);
  238. mather->len ++;
  239. mather->status = LEXMATHER_ING_1;
  240. }
  241. else if (mather->status == LEXMATHER_ING_1)
  242. mather->status = LEXMATHER_END_1;
  243. else
  244. mather->status = LEXMATHER_MISTAKE;
  245. else
  246. mather->status = LEXMATHER_MISTAKE;
  247. }
  248. void backslashMather(wint_t p, LexMather *mather){
  249. if (mather->status == LEXMATHER_START)
  250. if (p == L'\\')
  251. mather->status = LEXMATHER_ING_1;
  252. else
  253. mather->status = LEXMATHER_MISTAKE;
  254. else if (mather->status == LEXMATHER_ING_1) {
  255. if (p == WEOF)
  256. mather->status = LEXMATHER_END_1;
  257. else if (p == L'\n')
  258. mather->status = LEXMATHER_ING_2;
  259. }
  260. else if (mather->status == LEXMATHER_ING_2)
  261. mather->status = LEXMATHER_END_1;
  262. else
  263. mather->status = LEXMATHER_MISTAKE;
  264. }
  265. void commentMather(wint_t p, LexMather *mather){
  266. if (mather->status == LEXMATHER_START) {
  267. if (p == L'#')
  268. mather->status = LEXMATHER_ING_1;
  269. else
  270. mather->status = LEXMATHER_MISTAKE;
  271. }
  272. else if (mather->status == LEXMATHER_ING_1) { // 匹配到1个#的模式
  273. if (p == L'#')
  274. mather->status = LEXMATHER_ING_3;
  275. else if (p == L'\n' || p == WEOF)
  276. mather->status = LEXMATHER_END_1;
  277. else
  278. mather->status = LEXMATHER_ING_2;
  279. }
  280. else if (mather->status == LEXMATHER_ING_2){ // 单#匹配模式
  281. if (p == L'\n' || p == WEOF)
  282. mather->status = LEXMATHER_END_1;
  283. }
  284. else if (mather->status == LEXMATHER_ING_3) { // 双#匹配模式
  285. if (p == L'#')
  286. mather->status = LEXMATHER_ING_4;
  287. else if (p == WEOF)
  288. mather->status = LEXMATHER_END_1;
  289. }
  290. else if (mather->status == LEXMATHER_ING_4) {
  291. if (p == L'#')
  292. mather->status = LEXMATHER_ING_5;
  293. else
  294. mather->status = LEXMATHER_ING_3;
  295. }
  296. else if (mather->status == LEXMATHER_ING_5)
  297. mather->status = LEXMATHER_END_1;
  298. else
  299. mather->status = LEXMATHER_MISTAKE;
  300. }
  301. /**
  302. * 开始匹配,返回的int即checkoutMather返回的值(匹配成功的匹配器的索引)
  303. * @param file
  304. * @param mathers
  305. * @return
  306. */
  307. int getMatherStatus(LexFile *file, LexMathers *mathers) {
  308. int status = -1;
  309. wint_t p;
  310. setupMathers(mathers);
  311. while (status == -1){
  312. p = readChar(file);
  313. if (pm_KeyInterrupt == signal_appear) {
  314. pm_KeyInterrupt = signal_check;
  315. file->errsyntax = L"singal KeyInterrupt";
  316. return -3;
  317. }
  318. file->errsyntax = NULL;
  319. numberMather(p ,mathers->mathers[MATHER_NUMBER]);
  320. varMather(p ,mathers->mathers[MATHER_VAR]);
  321. spaceMather(p ,mathers->mathers[MATHER_SPACE]);
  322. stringMather(p, mathers->mathers[MATHER_STRING], file);
  323. backslashMather(p, mathers->mathers[MATHER_NOTENTER]);
  324. commentMather(p, mathers->mathers[MATHER_COMMENT]);
  325. aCharMather(p, mathers->mathers[MATHER_ENTER], '\n');
  326. aCharMather(p, mathers->mathers[MATHER_EOF], WEOF);
  327. strMatherMacro(MATHER_IF, "if");
  328. strMatherMacro(MATHER_ELIF, "elif");
  329. strMatherMacro(MATHER_WHILE, "while");
  330. strMatherMacro(MATHER_FOR, "for");
  331. strMatherMacro(MATHER_IN, "in");
  332. strMatherMacro(MATHER_TRY, "try");
  333. strMatherMacro(MATHER_EXCEPT, "catch");
  334. strMatherMacro(MATHER_AS, "as");
  335. strMatherMacro(MATHER_WITH, "with");
  336. strMatherMacro(MATHER_DO, "do");
  337. strMatherMacro(MATHER_ELSE, "else");
  338. strMatherMacro(MATHER_FINALLY, "end");
  339. strMatherMacro(MATHER_DEFAULT, "level");
  340. strMatherMacro(MATHER_GLOBAL, "global");
  341. strMatherMacro(MATHER_NONLOCAL, "nlocal");
  342. strMatherMacro(MATHER_PUBLIC, "pub");
  343. strMatherMacro(MATHER_PROTECT, "pro");
  344. strMatherMacro(MATHER_PRIVATE, "pri");
  345. strMatherMacro(MATHER_TRUE, "true");
  346. strMatherMacro(MATHER_FALSE, "false");
  347. strMatherMacro(MATHER_NULL, "null");
  348. strMatherMacro(MATHER_DEF, "fun");
  349. strMatherMacro(MATHER_CLASS, "class");
  350. strMatherMacro(MATHER_BLOCK, "code");
  351. strMatherMacro(MATHER_BREAK, "break");
  352. strMatherMacro(MATHER_CONTINUE, "continue");
  353. strMatherMacro(MATHER_REGO, "fall");
  354. strMatherMacro(MATHER_RESTART, "restart");
  355. strMatherMacro(MATHER_RETURN, "return");
  356. strMatherMacro(MATHER_YIELD, "yield");
  357. strMatherMacro(MATHER_IMPORT, "import");
  358. strMatherMacro(MATHER_INCLUDE, "include");
  359. charMatherMacro(MATHER_ADD, '+');
  360. charMatherMacro(MATHER_SUB, '-');
  361. charMatherMacro(MATHER_MUL, '*');
  362. charMatherMacro(MATHER_DIV, '/');
  363. strMatherMacro(MATHER_INTDIV, "//");
  364. charMatherMacro(MATHER_PER, '%');
  365. strMatherMacro(MATHER_POW, "**");
  366. strMatherMacro(MATHER_EQ, "==");
  367. strMatherMacro(MATHER_MOREEQ, ">=");
  368. strMatherMacro(MATHER_LESSEQ, "<=");
  369. charMatherMacro(MATHER_MORE, '>');
  370. charMatherMacro(MATHER_LESS, '<');
  371. strMatherMacro(MATHER_NOTEQ, "!=");
  372. charMatherMacro(MATHER_BITAND, '&');
  373. charMatherMacro(MATHER_BITOR, '|');
  374. charMatherMacro(MATHER_BITXOR, '^');
  375. charMatherMacro(MATHER_BITNOT, '~');
  376. strMatherMacro(MATHER_BITLEFT, "<<");
  377. strMatherMacro(MATHER_BITRIGHT, ">>");
  378. strMatherMacro(MATHER_BOOLAND, "and");
  379. strMatherMacro(MATHER_BOOLOR, "or");
  380. strMatherMacro(MATHER_BOOLNOT, "not");
  381. charMatherMacro(MATHER_ASSIGNMENT, '=');
  382. charMatherMacro(MATHER_POINT, '.');
  383. charMatherMacro(MATHER_AT, '@');
  384. charMatherMacro(MATHER_SVAR, '$');
  385. charMatherMacro(MATHER_LP, '(');
  386. charMatherMacro(MATHER_RP, ')');
  387. charMatherMacro(MATHER_LB, '[');
  388. charMatherMacro(MATHER_RB, ']');
  389. charMatherMacro(MATHER_LC, '{');
  390. charMatherMacro(MATHER_RC, '}');
  391. charMatherMacro(MATHER_COMMA, ',');
  392. charMatherMacro(MATHER_COLON, ':');
  393. charMatherMacro(MATHER_SEMICOLON, ';');
  394. strMatherMacro(MATHER_LINK, "->");
  395. strMatherMacro(MATHER_RAISE, "throw");
  396. strMatherMacro(MATHER_FROM, "from");
  397. strMatherMacro(MATHER_ASSERT, "assert");
  398. strMatherMacro(MATHER_LAMBDA, "def");
  399. strMatherMacro(MATHER_GOTO, "goto");
  400. strMatherMacro(MATHER_LABEL, "mark");
  401. strMatherMacro(MATHER_PASSVALUE, "...");
  402. strMatherMacro(MATHER_DEL, "del");
  403. status = checkoutMather(mathers, MATHER_MAX);
  404. }
  405. if (status != MATHER_ENTER)
  406. backChar(file);
  407. return status;
  408. }
  409. int lexFilter(LexFile *file, int status){
  410. if (status == MATHER_SPACE ||
  411. status == MATHER_NOTENTER ||
  412. status == MATHER_COMMENT ||
  413. file->filter_data.enter != 0 && status == MATHER_ENTER)
  414. return -1;
  415. return status;
  416. }
  417. /**
  418. * getMatherStatus的高级封装,若匹配到空格则自动忽略(再次匹配)
  419. * @param file
  420. * @param mathers
  421. * @return
  422. */
  423. Token *getToken(LexFile *file, LexMathers *mathers) {
  424. int status = MATHER_SPACE;
  425. int filter;
  426. do
  427. status = getMatherStatus(file, mathers);
  428. while ((filter = lexFilter(file, status)) == -1);
  429. if (status == -2 || status == -3)
  430. return makeLexToken(status, file->errsyntax, NULL, file->line);
  431. return makeLexToken(filter, mathers->mathers[status]->str, mathers->mathers[status]->second_str, file->line);
  432. }