Advertisement
Guest User

Untitled

a guest
May 27th, 2015
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.11 KB | None | 0 0
  1. %{
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdarg.h>
  5. #include "types.h"
  6. #define YYDEBUG 0
  7. /* prototypes */
  8. nodeType *opr(int oper, int nops, ...);
  9. nodeType *id(int i);
  10. nodeType *con(int value);
  11. void freeNode(nodeType *p);
  12. void yyerror(char *s);
  13.  
  14. int sym[26]; /* symbol table */
  15.  
  16. %}
  17.  
  18. %union {
  19. int iValue; /* integer value */
  20. char sIndex; /* symbol table index */
  21. nodeType *nPtr; /* node pointer */
  22. };
  23.  
  24. %token <iValue> INTEGER
  25. %token <sIndex> VARIABLE
  26. %token WHILE IF PRINT START FINISH DO
  27. %nonassoc IFX
  28. %nonassoc ELSE
  29.  
  30. %left GE LE EQ NE '>' '<'
  31. %left '+' '-'
  32. %left '*' '/'
  33. %nonassoc UMINUS
  34.  
  35. %type <nPtr> statement expr stmt_list
  36.  
  37. %start program
  38.  
  39. %%
  40.  
  41. program : function '.' { exit(0); }
  42. ;
  43.  
  44. function : function statement { ex($2); freeNode($2); }
  45. | /* NULL */
  46. ;
  47.  
  48.  
  49.  
  50. statement : ';' { $$ = opr('\n', 2, NULL, NULL); }
  51. | expr { $$ = $1; }
  52. | PRINT expr { $$ = opr(PRINT, 1, $2); }
  53. | VARIABLE '=' expr { $$ = opr('=', 2, id($1), $3); }
  54. | WHILE expr DO statement { $$ = opr(WHILE, 2, $2, $4); }
  55. | IF expr statement %prec IFX { $$ = opr(IF, 2, $2, $3); }
  56. | IF expr statement ELSE statement { $$ = opr(IF, 3, $2, $3, $5); }
  57. | START stmt_list FINISH { $$ = $2; }
  58. ;
  59.  
  60. stmt_list : statement
  61. | stmt_list statement { $$ = opr('\n', 2, $1, $2); }
  62. ;
  63.  
  64. expr : INTEGER { $$ = con($1); }
  65. | VARIABLE { $$ = id($1); }
  66. | '-' expr %prec UMINUS { $$ = opr(UMINUS, 1, $2); }
  67. | expr '+' expr { $$ = opr('+', 2, $1, $3); }
  68. | expr '-' expr { $$ = opr('-', 2, $1, $3); }
  69. | expr '*' expr { $$ = opr('*', 2, $1, $3); }
  70. | expr '/' expr { $$ = opr('/', 2, $1, $3); }
  71. | expr '<' expr { $$ = opr('<', 2, $1, $3); }
  72. | expr '>' expr { $$ = opr('>', 2, $1, $3); }
  73. | expr GE expr { $$ = opr(GE, 2, $1, $3); }
  74. | expr LE expr { $$ = opr(LE, 2, $1, $3); }
  75. | expr NE expr { $$ = opr(NE, 2, $1, $3); }
  76. | expr EQ expr { $$ = opr(EQ, 2, $1, $3); }
  77. | '(' expr ')' { $$ = $2; }
  78. ;
  79.  
  80. %%
  81.  
  82. nodeType *con(int value)
  83. {
  84. nodeType *p;
  85.  
  86. /* allocate node */
  87. if ((p = malloc(sizeof(conNodeType))) == NULL)
  88. yyerror("out of memory");
  89. /* copy information */
  90. p->type = typeCon;
  91. p->con.value = value;
  92. return p;
  93. }
  94.  
  95. nodeType *id(int i)
  96. {
  97. nodeType *p;
  98. /* allocate node */
  99. if ((p = malloc(sizeof(idNodeType))) == NULL)
  100. yyerror("out of memory");
  101. /* copy information */
  102. p->type = typeId;
  103. p->id.i = i;
  104. return p;
  105. }
  106.  
  107. nodeType *opr(int oper, int nops, ...)
  108. {
  109. va_list ap;
  110. nodeType *p;
  111. size_t size;
  112. int i;
  113.  
  114. /* allocate node */
  115. size = sizeof(oprNodeType) + (nops - 1) * sizeof(nodeType*);
  116. if ((p = malloc(size)) == NULL)
  117. yyerror("out of memory");
  118. /* copy information */
  119. p->type = typeOpr;
  120. p->opr.oper = oper;
  121. p->opr.nops = nops;
  122. va_start(ap, nops);
  123. for (i = 0; i < nops; i++)
  124. p->opr.op[i] = va_arg(ap, nodeType*);
  125. va_end(ap);
  126.  
  127. return p;
  128. }
  129.  
  130. void freeNode(nodeType *p)
  131. {
  132. int i;
  133.  
  134. if (!p)
  135. return;
  136. if (p->type == typeOpr) {
  137. for (i = 0; i < p->opr.nops; i++)
  138. freeNode(p->opr.op[i]);
  139. }
  140. free (p);
  141. }
  142.  
  143. int ex(nodeType *p)
  144. {
  145. if (!p)
  146. return 0;
  147.  
  148. switch(p->type)
  149. {
  150. case typeCon: return p->con.value;
  151. case typeId: return sym[p->id.i];
  152. case typeOpr: switch(p->opr.oper)
  153. {
  154. case WHILE: while(ex(p->opr.op[0]))
  155. ex(p->opr.op[1]);
  156. return 0;
  157. case IF: if (ex(p->opr.op[0]))
  158. ex(p->opr.op[1]);
  159. else if (p->opr.nops > 2)
  160. ex(p->opr.op[2]);
  161. return 0;
  162. case PRINT: printf("%d\n", ex(p->opr.op[0]));
  163. return 0;
  164. case '\n': ex(p->opr.op[0]);
  165. return ex(p->opr.op[1]);
  166. case '=': return sym[p->opr.op[0]->id.i] = ex(p->opr.op[1]);
  167. case UMINUS: return -ex(p->opr.op[0]);
  168. case '+': return ex(p->opr.op[0]) + ex(p->opr.op[1]);
  169. case '-': return ex(p->opr.op[0]) - ex(p->opr.op[1]);
  170. case '*': return ex(p->opr.op[0]) * ex(p->opr.op[1]);
  171. case '/': return ex(p->opr.op[0]) / ex(p->opr.op[1]);
  172. case '<': return ex(p->opr.op[0]) < ex(p->opr.op[1]);
  173. case '>': return ex(p->opr.op[0]) > ex(p->opr.op[1]);
  174. case GE: return ex(p->opr.op[0]) >= ex(p->opr.op[1]);
  175. case LE: return ex(p->opr.op[0]) <= ex(p->opr.op[1]);
  176. case NE: return ex(p->opr.op[0]) != ex(p->opr.op[1]);
  177. case EQ: return ex(p->opr.op[0]) == ex(p->opr.op[1]);
  178. }
  179. }
  180. }
  181.  
  182. void yyerror(char *s)
  183. {
  184. fprintf(stdout, "%s\n", s);
  185. }
  186.  
  187. int main(void)
  188. {
  189. #if YYDEBUG
  190. yydebug = 1;
  191. #endif
  192. yyparse();
  193. return 0;
  194. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement