当前位置:   article > 正文

词法分析器(纯c语言)_c语言词法分析器代码

c语言词法分析器代码

一、原文章:词法分析器(分析C语言)

二、该词法分析器种别码表

 三、词法分析器实现思路描述:

1.首先用一个数组来存储txt文本中非空白字符,并将存储字符的个数记录下来。

2.用scan()函数扫描数组中的字符,用index来定位当前扫描到的字符位置。

3.判断当前字符是哪种类型:

   (1)若是字母,则有可能是关键字或标识符,需继续看下一个字符。若是关键字,再判断具体是哪个种别码;若是标识符,种别码为0。

   (2)若是数字,是常量,种别码为24。

   (3)若是运算符或界符,则需继续看下一个字符(因为可能是<=、>=、==、!=),再判断具体是哪个种别码。

   (4)若不是以上三种,则输出。

二、用C语言改写并优化:

  1. #pragma warning(disable:4996)
  2. #include <stdio.h>
  3. #include <ctype.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. const int MAXN = 1000;
  7. const int MINN = 20;
  8. bool isKey(char* s) //是否是关键字
  9. {
  10. const char* letter[6] = { "main","int","if","else","while","do" };
  11. for (int i = 0; i < 6; i++)
  12. {
  13. if (strcmp(s, letter[i]) == 0)
  14. return true;
  15. }
  16. return false;
  17. }
  18. bool isOpebounder(char s) //是否是界符或运算符
  19. {
  20. const char* str = "><=!(){},;+-*/";
  21. if (memchr(str, s, strlen(str)) != NULL)
  22. return true;
  23. else
  24. return false;
  25. }
  26. int kindofKey(char* str) //判断哪种关键字 并返回其种别码
  27. {
  28. const char* key[6] = { "main","int","if","else","while","do" };
  29. const int arr[6] = { 1,2,3,4,5,6 };
  30. for (int i = 0; i < 6; i++)
  31. {
  32. if (strcmp(str, key[i]) == 0)
  33. return arr[i];
  34. }
  35. }
  36. int kindofOpebounder(char* str) //判断哪种运算符和界符 并返回其种别码
  37. {
  38. const char* opebounder[17] = { "<",">","!=",">=","<=","==",",",";","(",")","{","}","+","-","*","/","=" };
  39. const int arr[MINN] = { 7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 };
  40. for (int i = 0; i < 17; i++)
  41. {
  42. if (strcmp(str, opebounder[i]) == 0)
  43. return arr[i];
  44. }
  45. }
  46. char* firstLetter(char* s) //首字符为字母
  47. {
  48. int size = 0;//单词长度
  49. char str[MINN] = ""; //单词
  50. char c; //存储当前字符的下一个 方便作为实参以识别类型
  51. str[size++] = *s; //保存当前字符并增加长度
  52. while (c = *(s + size))
  53. {
  54. if (islower(c) || isdigit(c)) //下一个字符是字母或数字则保存在str中
  55. str[size++] = c;
  56. else
  57. break;
  58. if (isKey(str)) //如果单词恰好是关键字 则终止循环
  59. break;
  60. }
  61. return str;
  62. }
  63. char* firstNumber(char* s) //首字符为数字
  64. {
  65. int size = 0;
  66. char str[MINN] = "";
  67. char c;
  68. str[size++] = *s;
  69. while (c = *(s + size))
  70. {
  71. if (isdigit(c)) //下一个字符是字母或数字则保存在str中
  72. str[size++] = c;
  73. else
  74. break;
  75. }
  76. return str;
  77. }
  78. char* firstOpebounder(char* s) //首字符为运算符和界符
  79. {
  80. char arr[MINN] = ">=<!";
  81. char str[MINN] = "";
  82. char c = *(s + 1);
  83. str[0] = *s;
  84. if (memchr(arr, *s, strlen(arr)) != NULL)
  85. {
  86. if (c == '=')
  87. str[1] = '=';
  88. }
  89. return str;
  90. }
  91. int Type(char* s) //判断单词的首字母为哪种类型
  92. {
  93. if (islower(*s))
  94. return 1;
  95. else if (isdigit(*s))
  96. return 2;
  97. else if (isOpebounder(*s))
  98. return 3;
  99. else
  100. return 4;
  101. }
  102. void scan(char* s, int n)
  103. {
  104. for (int index = 0; index < n;index++)
  105. {
  106. char str[MINN] = ""; //存储单词
  107. switch (Type(s + index))
  108. {
  109. case 1:
  110. {
  111. //首字符为字母 可能是关键字或标识符 接下来持续读取字母形成单词
  112. strcpy(str, firstLetter(s + index));
  113. if (isKey(str))
  114. printf("(%s,%d)\n", str, kindofKey(str));
  115. else
  116. printf("(%s,0)\n", str);
  117. index += (strlen(str) - 1);
  118. break;
  119. }
  120. case 2:
  121. {
  122. //首字符为数字,只能是常量
  123. strcpy(str, firstNumber(s+index));
  124. printf("(%s,24)\n", str);
  125. index += (strlen(str) - 1);
  126. break;
  127. }
  128. case 3:
  129. {
  130. //首字符为运算符和界符
  131. strcpy(str, firstOpebounder(s+index));
  132. printf("(%s,%d)\n", str, kindofOpebounder(str));
  133. index += (strlen(str) - 1);
  134. break;
  135. }
  136. default:
  137. {
  138. //其他
  139. printf("(%c,error)\n", *(s+index));
  140. }
  141. }
  142. }
  143. }
  144. int main(void)
  145. {
  146. char letter[MAXN] = ""; //存储要扫描的字符
  147. int size = 0; //字符的个数
  148. //与s.txt文件连接并读取里面的内容
  149. FILE* fp;
  150. fp = fopen("s.txt", "r");
  151. char ch = getc(fp);
  152. while (ch != EOF)
  153. {
  154. if (ch != ' '&&ch !='\n') //保存非空白字符
  155. {
  156. letter[size] = ch;
  157. size++;
  158. }
  159. ch = getc(fp);
  160. }
  161. fclose(fp);
  162. //开始扫,并将结果以二元的形式打印在屏幕上
  163. scan(letter, size);
  164. return 0;
  165. }

三、文本内容及结果截图:

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/294195
推荐阅读
相关标签
  

闽ICP备14008679号