mylex.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. #include "Lpars.h"
  2. #include <stdio.h>
  3. #include <ctype.h>
  4. /* This file contains the function mylex() which recognizes the following
  5. * tokens :
  6. * EOFILE
  7. * C_INSTR - 'C_loc', 'C_lol', etc.
  8. * DEF_C_INSTR - 'C_loe..', 'C_ste..', '..icon, '..fcon', etc
  9. * CONDITION - C-expression, for example: '$1 == 481'
  10. * ARROW - '==>'
  11. * CALL - C-style functioncall, for example: 'error( 17)'
  12. * ASSEM_INSTR - C-style string, for example: '"mov r0, (r1)"'
  13. * DEFAULT - 'default'
  14. * ERROR - An error occured in one of the tokens.
  15. *
  16. * If the input matches non of these tokens the next character will be returned.
  17. *
  18. * Besides mylex() the following variable is exported :
  19. *
  20. * char yytext[]; - Contains the string representation of the current
  21. * token.
  22. * char *next; - Points to the first free position in yytext[].
  23. */
  24. #define YYTEXT 65536
  25. char yytext[YYTEXT], /* string-buffer for the token */
  26. *next; /* points to the first free posistion in yytext[] */
  27. extern char scanc();
  28. #define FALSE 0
  29. #define TRUE 1
  30. int CD_pos = FALSE; /* 'CD_pos' is used as a flag to signal if it is
  31. * possible to match a CONDITION or DEFAULT-token at
  32. * this moment. Thus mylex() knows about the grammar
  33. * of the "EM_table"!!
  34. * This flag is needed because CALL is a subset of
  35. * CONDITION.
  36. */
  37. int CALL_pos = FALSE; /* Needed to distinguish between
  38. * C_INSTR CONDITION and CALL
  39. */
  40. static char skip_space();
  41. static read_string();
  42. int mylex()
  43. {
  44. char c;
  45. static int special = FALSE; /* rule with conditions + default ? */
  46. next = yytext;
  47. c = *next++ = skip_space();
  48. switch ( c) {
  49. case EOF : next = yytext;
  50. return( 0);
  51. case '"' : read_string();
  52. return( ASSEM_INSTR);
  53. case '.' : c = scanc();
  54. backc( c);
  55. if ( c != '.') { /* Just a plain '.', not something like
  56. * '..icon'.
  57. */
  58. if ( special)
  59. CD_pos = TRUE;
  60. CALL_pos = FALSE;
  61. return( '.');
  62. }
  63. break;
  64. case ';' : return( ';');
  65. case '=' : if ( arrow()) {
  66. CD_pos = FALSE;
  67. CALL_pos = TRUE;
  68. return( ARROW);
  69. }
  70. break;
  71. case 'd' : if ( CD_pos && _default()) {
  72. CD_pos = FALSE;
  73. special = FALSE;
  74. return( DEFAULT);
  75. }
  76. break;
  77. }
  78. /* Possible tokens at this place : CONDITION, CALL, C_INSTR,
  79. * DEF_C_INSTR
  80. */
  81. if ( CD_pos) {
  82. read_condition();
  83. CD_pos = FALSE;
  84. special = TRUE;
  85. return( CONDITION);
  86. }
  87. if ( isalpha( c)) {
  88. read_ident();
  89. if ( CALL_pos) {
  90. c = skip_space();
  91. if ( c == '(') {
  92. *next++ = c;
  93. read_call();
  94. return( CALL);
  95. }
  96. else {
  97. backc( c);
  98. return( ERROR);
  99. }
  100. }
  101. else {
  102. if ( is_DEF_C_INSTR( yytext)) {
  103. CD_pos = TRUE;
  104. return( DEF_C_INSTR);
  105. }
  106. if ( is_C_INSTR( yytext)) {
  107. CD_pos = TRUE;
  108. return( C_INSTR);
  109. }
  110. return( ERROR);
  111. }
  112. }
  113. if ( c == '.') {
  114. c = scanc();
  115. if ( c == '.') {
  116. *next++ = '.';
  117. read_ident();
  118. if ( is_DEF_C_INSTR( yytext)) {
  119. CD_pos = TRUE;
  120. return( DEF_C_INSTR);
  121. }
  122. return( ERROR);
  123. }
  124. else {
  125. backc( c);
  126. return( '.');
  127. }
  128. }
  129. return( c);
  130. }
  131. static int isletter( c)
  132. char c;
  133. {
  134. return( isalpha( c) || isdigit( c) || c == '_');
  135. }
  136. static char skip_space()
  137. {
  138. char c;
  139. while ( isspace( c = scanc()))
  140. ;
  141. return( c);
  142. }
  143. /* first character has been read */
  144. static read_string()
  145. /* match something like "mov r0, (r1)".
  146. * strip the double quotes off! Inside a string, the character '"' must
  147. * be preceded by a '\'.
  148. */
  149. {
  150. next--;
  151. while( ( *next = scanc()) != '"' || *(next-1) == '\\')
  152. next++;
  153. }
  154. int arrow() /* '==>' */
  155. {
  156. if ( ( *next++ = scanc()) == '=')
  157. if ( ( *next++ = scanc()) == '>')
  158. return( TRUE);
  159. else
  160. backc( *--next);
  161. else
  162. backc( *--next);
  163. return( FALSE);
  164. }
  165. int _default() /* 'default' */
  166. {
  167. char c;
  168. if ( ( *next++ = scanc()) == 'e')
  169. if ( ( *next++ = scanc()) == 'f')
  170. if ( ( *next++ = scanc()) == 'a')
  171. if ( ( *next++ = scanc()) == 'u')
  172. if ( ( *next++ = scanc()) == 'l')
  173. if ( ( *next++ = scanc()) == 't')
  174. if ( !isletter( c = skip_space())) {
  175. backc( c);
  176. return( TRUE);
  177. }
  178. else
  179. backc( c);
  180. else
  181. backc( *--next);
  182. else
  183. backc( *--next);
  184. else
  185. backc( *--next);
  186. else
  187. backc( *--next);
  188. else
  189. backc( *--next);
  190. else
  191. backc( *--next);
  192. return( FALSE);
  193. }
  194. read_ident()
  195. {
  196. char c;
  197. while ( isletter( c = scanc()))
  198. *next++ = c;
  199. backc( c);
  200. }
  201. read_call()
  202. {
  203. int n = 1;
  204. while ( TRUE)
  205. switch( *next++ = scanc()) {
  206. case EOF : return;
  207. case '(' : n++;
  208. break;
  209. case ')' : n--;
  210. if ( n == 0)
  211. return;
  212. break;
  213. }
  214. }
  215. read_condition()
  216. /* A CONDITION is followed by '==>'
  217. */
  218. {
  219. while ( TRUE) {
  220. switch ( *next++ = scanc()) {
  221. case EOF : return;
  222. case '=' : if ( arrow()) {
  223. backc( '>');
  224. backc( '=');
  225. backc( '=');
  226. next -= 3;
  227. return;
  228. }
  229. break;
  230. }
  231. }
  232. }
  233. is_C_INSTR( str)
  234. char *str;
  235. {
  236. if ( *str == 'C' && *(str+1) == '_') /* C_xxx */
  237. return( TRUE);
  238. else
  239. return( FALSE);
  240. }
  241. is_DEF_C_INSTR( str)
  242. char *str;
  243. /* yytext[] contains either '..[letter]*' ( 2 dots possibly followed by an
  244. * identifer) * or '[letter]+' ( just an identifier)
  245. * Try to match something like 'C_loe..' or '..icon'
  246. */
  247. {
  248. if ( *str == '.' && *(str+1) == '.')
  249. return( next > yytext+1);
  250. if ( ( *next++ = scanc()) == '.')
  251. if ( ( *next++ = scanc()) == '.')
  252. return( next > yytext+1);
  253. else
  254. backc( *--next);
  255. else
  256. backc( *--next);
  257. return( FALSE);
  258. }