Advertisement
Guest User

Untitled

a guest
Nov 19th, 2019
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.51 KB | None | 0 0
  1.  
  2.  
  3. #include <ctype.h> //isspace
  4. #include <math.h> //pow
  5. #include <stdio.h>
  6. #include <stdlib.h> //NULL EOF
  7.  
  8. // Token types
  9. enum tokens {
  10. ADD, SUB, MUL, DIV, MOD, POW,
  11. OBR, CBR,
  12. VAL, NON,
  13. ERR, NEXT,
  14. EXP
  15. // More later
  16. };
  17.  
  18. //Token data structure
  19.  
  20. typedef struct token {
  21. //enum tokens type; if doesn't work
  22. tokens type;
  23. double value; //item to save the value
  24. } Token;
  25.  
  26. //Scanner states
  27. enum states{
  28. INIT,
  29. ZERO,
  30. DOT,
  31. FRACT,
  32. EXPO,
  33. PRESHIFT,
  34. SHIFT
  35. };
  36.  
  37.  
  38.  
  39. // SCANNER (LEXICAL ANALYZER)
  40. Token scanner() {
  41. Token token = { NON, 0 };
  42. states state = INIT;
  43. int c;
  44. static int last = EOF; //indicator that there was any remember symbol
  45.  
  46. if(last != EOF && !isspace(last))
  47. c = last;
  48. else
  49. while(isspace(c = getchar())); //We will skip all the white space characters
  50.  
  51. last = EOF;
  52.  
  53. switch(c){
  54. case '+':
  55. token.type = ADD;
  56. return token;
  57. case '-':
  58. token.type = SUB;
  59. return token;
  60. case '*':
  61. token.type = MUL;
  62. return token;
  63. case '/':
  64. token.type = DIV;
  65. return token;
  66. case '%':
  67. token.type = MOD;
  68. return token;
  69. case '^':
  70. token.type = POW;
  71. return token;
  72. case '(':
  73. token.type = OBR;
  74. return token;
  75. case ')':
  76. token.type = CBR;
  77. return token;
  78. case EOF:
  79. return token;
  80. default:
  81. if(isdigit(c))
  82. break;
  83.  
  84. token.type = ERR;
  85. return token;
  86.  
  87. }
  88.  
  89. token.type = VAL;
  90. token.value += c - '0'; //variable that Host the character that host the number
  91.  
  92. double fractional = 1;
  93.  
  94. int exponential=0;
  95.  
  96. int sign = 0;
  97. for(;;){
  98. c = getchar();
  99. switch(state){
  100. case INIT:
  101. if(isdigit(c))
  102. token.value = token.value *10 + c - '0'; //order of our numerical decimal base
  103. else
  104. {
  105. if(c == '.')
  106. state = DOT;
  107. else if(c=='e' || c=='E') //EXPONENTIAL PART
  108. state=EXPO;
  109. else
  110. {
  111. last = c;
  112. return token;
  113. }
  114. }
  115. break;
  116.  
  117. case DOT:
  118. if(!isdigit(c))
  119. {
  120. token.type = ERR;
  121. return token;
  122. }
  123.  
  124. fractional /= 10;
  125. token.value += fractional * (c - '0');
  126. state = FRACT;
  127. break;
  128.  
  129. case FRACT:
  130. if(isdigit(c))
  131. {
  132. fractional /= 10;
  133. token.value += fractional * (c - '0');
  134. }else
  135. //Exponential TODO
  136. if(c == 'e' || 'E')
  137. state = EXPO;
  138. else
  139. {
  140. last = c;
  141. return token;
  142. }
  143. break;
  144. //case TODO after the Exponential part
  145. case EXPO:
  146. if(!isdigit(c))
  147. {
  148. if(c=='-'){
  149. if(isdigit(c=getchar())){
  150. do{
  151. exponential = exponential*10 + c - '0';
  152. exponential*=1;
  153. }while(isdigit(c=getchar()));
  154. token.value=pow(token.value,exponential);
  155. return token;
  156. }
  157. }
  158. token.type=ERR;
  159. return token;
  160. }
  161. else{
  162. do{
  163. exponential = exponential*10 + c - '0';
  164. }while(isdigit(c=getchar()));
  165. token.value=pow(token.value,exponential);
  166. return token;
  167. }
  168. break;
  169. }//chiusura switch
  170.  
  171. }
  172. return token;
  173.  
  174.  
  175.  
  176.  
  177. }
  178.  
  179. //pushdown
  180. typedef struct pushdown Stack;
  181. struct pushdown{
  182. Token token;
  183. Stack *next;
  184. };
  185.  
  186. Stack *pop(Stack *stack){
  187. if(stack != NULL)
  188. {
  189. Stack *tmp = stack->next;
  190. free(stack);
  191. stack = tmp;
  192. }
  193. return stack;
  194.  
  195. }
  196.  
  197. void freeStack(Stack *stack){
  198. while(stack != NULL)
  199. stack = pop(stack);
  200. }
  201.  
  202.  
  203. Stack *push(Stack *stack, Token token){
  204. Stack *tmp;
  205. if((tmp = (Stack *)malloc(sizeof(Stack))) == NULL)
  206. {
  207. freeStack(stack);
  208. return NULL;
  209. }
  210. tmp->token = token;
  211. tmp->next = stack;
  212. return tmp;
  213. }
  214. /*void printStack(Stack *stack){
  215. if(stack != NULL){
  216. if(stack->token.type == VAL || stack->token.type == EXP)
  217. printf("-[%d|%g]", stack->token.type, stack->token.value);
  218. printStack(stack->next);
  219. }
  220. else
  221. printf("\n");
  222. }
  223. */
  224. //Top most terminal
  225.  
  226. tokens topTerminal(Stack *stack){
  227. for(; stack != NULL; stack = stack->next)
  228. if(stack->token.type != EXP){
  229. return stack->token.type;
  230. }
  231. return ERR; //Fatal Error
  232. }
  233.  
  234.  
  235. //Table values
  236. enum table { L,G,E,B,A};
  237. //Precedence Table
  238. static table precTable[10][10] = {
  239. // + - * / % ^ ( ) N $
  240. /* + */ { G, L, L, L, L, L, L, G, L, G },
  241. /* - */ { G, L, L, L, L, L, L, G, L, G },
  242. /* * */ { G, L, G, G, G, L, L, G, L, G },
  243. /* / */ { G, L, G, G, G, L, L, G, L, G },
  244. /* % */ { G, L, G, G, G, L, L, G, L, G },
  245. /* ^ */ { G, L, G, G, G, L, L, G, L, G },
  246. /* ( */ { L, L, L, L, L, L, L, E, L, B },
  247. /* ) */ { G, G, G, G, G, G, B, G, B, G },
  248. /* N */ { G, G, G, G, G, G, B, G, B, G },
  249. /* $ */ { L, L, L, L, L, L, L, B, L, A },
  250. };
  251.  
  252. int main(){
  253. double value;
  254. Token token = {NON , 0}; //end marker
  255. Stack *stack = NULL;
  256. if((stack = push(stack, token)) == NULL)
  257. goto mallocError;
  258. token.type = NEXT;
  259.  
  260. // Parser Loop
  261. for(;;){
  262. if(token.type == NEXT)
  263. token = scanner();
  264. if(token.type == ERR)
  265. goto lexicalError;
  266.  
  267. switch(precTable[topTerminal(stack)][token.type]){
  268. case L:
  269. if((stack = push(stack, token))==NULL)
  270. goto mallocError;
  271. token.type = NEXT;
  272. break;
  273.  
  274. case E:
  275. Stack *tmp;
  276. if((tmp = push(stack, token))==NULL)
  277. goto mallocError;
  278. token.type = NEXT;
  279. stack = tmp;
  280. break;
  281.  
  282. case G:
  283. switch(topTerminal(stack)){
  284.  
  285. case ADD: //E->E + E
  286. if(stack->token.type != EXP)
  287. goto syntaxError;
  288. value = stack -> token.value;
  289. stack = pop(stack);
  290. if(stack->token.type != ADD)
  291. goto syntaxError;
  292. stack = pop(stack);
  293. if(stack->token.type != EXP)
  294. goto syntaxError;
  295. stack->token.value += value;
  296. continue;
  297.  
  298. case SUB: //E->E - E | E-> -E
  299. if(stack->token.type != EXP)
  300. goto syntaxError;
  301. value = stack->token.value;
  302. stack = pop(stack);
  303. if(stack->token.type != SUB)
  304. goto syntaxError;
  305. if(stack->next->token.type == EXP)
  306. {
  307. stack = pop(stack);
  308. stack->token.value -= value;
  309.  
  310. }
  311. else
  312. stack->token.value -= value;
  313. stack->token.type = EXP;
  314. continue;
  315.  
  316. case MUL: //E->E * E
  317. if(stack->token.type != EXP)
  318. goto syntaxError;
  319. value = stack -> token.value;
  320. stack = pop(stack);
  321. if(stack->token.type != MUL)
  322. goto syntaxError;
  323. stack = pop(stack);
  324. if(stack->token.type != EXP)
  325. goto syntaxError;
  326. stack->token.value *= value;
  327. continue;
  328.  
  329. case DIV:
  330. if(stack->token.type != EXP)
  331. goto syntaxError;
  332. value = stack->token.value;
  333. stack = pop(stack);
  334. if(stack->token.type != DIV)
  335. goto syntaxError;
  336. stack = pop(stack);
  337. if(stack->token.type != EXP)
  338. goto syntaxError;
  339. stack->token.value /= value;
  340. continue;
  341.  
  342. case MOD:
  343. if(stack->token.type != EXP)
  344. goto syntaxError;
  345. value = stack->token.value;
  346. stack = pop(stack);
  347. if(stack->token.type != MOD)
  348. goto syntaxError;
  349. stack = pop(stack);
  350. if(stack->token.type != EXP)
  351. goto syntaxError;
  352. stack->token.value = fmod(stack->token.value, value);
  353. continue;
  354.  
  355. case POW: // E^E
  356. if(stack->token.type != EXP)
  357. goto syntaxError;
  358. value = stack->token.value;
  359. stack = pop(stack);
  360. if(stack->token.type != POW)
  361. goto syntaxError;
  362. stack = pop(stack);
  363. if(stack->token.type != EXP)
  364. goto syntaxError;
  365. stack->token.value = pow(stack->token.value, value);
  366. continue;
  367.  
  368. case CBR:
  369. if(stack->token.type != CBR)
  370. goto syntaxError;
  371. stack = pop(stack);
  372. if(stack->token.type != EXP)
  373. goto syntaxError;
  374. value = stack->token.value;
  375. stack = pop(stack);
  376. if(stack->token.type != OBR)
  377. goto syntaxError;
  378. stack->token.value = value;
  379. stack->token.type = EXP;
  380. continue;
  381.  
  382.  
  383. case VAL: //E -> n rules on the notebook near the operand table
  384. if(stack->token.type != VAL)
  385. goto syntaxError;
  386. stack->token.type = EXP;
  387. continue;
  388.  
  389. }
  390.  
  391. case B:
  392. goto syntaxError;
  393.  
  394. case A:
  395. if(stack->token.type == EXP)
  396. printf("%g\n", stack->token.value);
  397. freeStack(stack);
  398. return 0;
  399.  
  400. default:
  401. goto fatalError;
  402. }
  403. }
  404.  
  405.  
  406.  
  407. mallocError:
  408. perror("malloc error");
  409. return 4;
  410. lexicalError:
  411. fprintf(stderr, "Lexical error\n");
  412. freeStack(stack);
  413. return 3;
  414. syntaxError:
  415. fprintf(stderr, "Syntax error\n");
  416. freeStack(stack);
  417. return 2;
  418. fatalError:
  419. fprintf(stderr, "Fatal error\n");
  420. freeStack(stack);
  421. return 1;
  422. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement