PageRenderTime 73ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/ngspice-23/src/xspice/cmpp/mod_yacc.y

#
Happy | 610 lines | 549 code | 61 blank | 0 comment | 0 complexity | 4b0ac9288b5b3123e455dd3aa1987210 MD5 | raw file
Possible License(s): LGPL-2.0, GPL-2.0, LGPL-2.1
  1. %{ /* $Id: mod_yacc.y,v 1.15 2011/05/08 08:48:43 rlar Exp $ */
  2. /*============================================================================
  3. FILE mod_yacc.y
  4. MEMBER OF process cmpp
  5. Copyright 1991
  6. Georgia Tech Research Corporation
  7. Atlanta, Georgia 30332
  8. All Rights Reserved
  9. PROJECT A-8503
  10. AUTHORS
  11. 9/12/91 Steve Tynor
  12. MODIFICATIONS
  13. <date> <person name> <nature of modifications>
  14. 20050420 Steven Borley Renamed strcmpi() to local_strcmpi() to avoid
  15. clash with strcmpi() in a windows header file.
  16. SUMMARY
  17. This file contains a BNF specification of the translation of
  18. cfunc.mod files to cfunc.c files, together with various support
  19. functions.
  20. INTERFACES
  21. mod_yyparse() - Function 'yyparse()' is generated automatically
  22. by UNIX 'yacc' utility and then converted to
  23. 'mod_yyparse()' by UNIX 'sed' utility under
  24. direction of Makefile.
  25. REFERENCED FILES
  26. mod_lex.l
  27. NON-STANDARD FEATURES
  28. Names of functions generated by 'yacc' are translated by 'sed'
  29. under direction of the Makefile to prevent collisions with
  30. functions generated from ifs_yacc.y.
  31. ============================================================================*/
  32. #include <assert.h>
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include "mod_yacc_y.h"
  36. extern int mod_yylex(void);
  37. #define yymaxdepth mod_yymaxdepth
  38. #define yyparse mod_yyparse
  39. #define yylex mod_yylex
  40. #define yyerror mod_yyerror
  41. #define yylval mod_yylval
  42. #define yychar mod_yychar
  43. #define yydebug mod_yydebug
  44. #define yypact mod_yypact
  45. #define yyr1 mod_yyr1
  46. #define yyr2 mod_yyr2
  47. #define yydef mod_yydef
  48. #define yychk mod_yychk
  49. #define yypgo mod_yypgo
  50. #define yyact mod_yyact
  51. #define yyexca mod_yyexca
  52. #define yyerrflag mod_yyerrflag
  53. #define yynerrs mod_yynerrs
  54. #define yyps mod_yyps
  55. #define yypv mod_yypv
  56. #define yys mod_yys
  57. #define yy_yys mod_yyyys
  58. #define yystate mod_yystate
  59. #define yytmp mod_yytmp
  60. #define yyv mod_yyv
  61. #define yy_yyv mod_yyyyv
  62. #define yyval mod_yyval
  63. #define yylloc mod_yylloc
  64. #define yyreds mod_yyreds
  65. #define yytoks mod_yytoks
  66. #define yylhs mod_yyyylhs
  67. #define yylen mod_yyyylen
  68. #define yydefred mod_yyyydefred
  69. #define yydgoto mod_yyyydgoto
  70. #define yysindex mod_yyyysindex
  71. #define yyrindex mod_yyyyrindex
  72. #define yygindex mod_yyyygindex
  73. #define yytable mod_yyyytable
  74. #define yycheck mod_yyyycheck
  75. #define yyname mod_yyyyname
  76. #define yyrule mod_yyyyrule
  77. Ifs_Table_t *mod_ifs_table;
  78. extern char *mod_yytext;
  79. extern FILE* mod_yyout;
  80. #include <string.h>
  81. #include <ctype.h>
  82. int mod_num_errors;
  83. #define BUFFER_SIZE 3000
  84. static char buffer [BUFFER_SIZE];
  85. static int buf_len;
  86. typedef enum {CONN, PARAM, STATIC_VAR} Id_Kind_t;
  87. /*--------------------------------------------------------------------------*/
  88. static char *subscript (Sub_Id_t sub_id)
  89. {
  90. if (sub_id.has_subscript) {
  91. return sub_id.subscript;
  92. } else {
  93. return "0";
  94. }
  95. }
  96. /*--------------------------------------------------------------------------*/
  97. static int
  98. local_strcmpi(char *s, char *t)
  99. /* string compare - case insensitive */
  100. {
  101. for (; *s && t && tolower(*s) == tolower(*t); s++, t++)
  102. ;
  103. if (*s && !*t) {
  104. return 1;
  105. }
  106. if (!*s && *t) {
  107. return -1;
  108. }
  109. if (! (*s || *t)) {
  110. return 0;
  111. }
  112. return (tolower(*s) - tolower(*t));
  113. }
  114. /*---------------------------------------------------------------------------*/
  115. static void put_type (FILE *fp, Data_Type_t type)
  116. {
  117. char ch = ' ';
  118. switch (type) {
  119. case INTEGER:
  120. ch = 'i';
  121. break;
  122. case REAL:
  123. ch = 'r';
  124. break;
  125. case COMPLEX:
  126. ch = 'c';
  127. break;
  128. case BOOLEAN:
  129. ch = 'b';
  130. break;
  131. case STRING:
  132. ch = 's';
  133. break;
  134. case POINTER:
  135. ch = 'p';
  136. break;
  137. }
  138. fprintf (fp, ".%cvalue", ch);
  139. }
  140. /*---------------------------------------------------------------------------*/
  141. static void put_conn_type (FILE *fp, Port_Type_t type)
  142. {
  143. char ch;
  144. switch (type) {
  145. case USER_DEFINED:
  146. ch = 'p';
  147. break;
  148. case DIGITAL:
  149. ch = 'p';
  150. break;
  151. default:
  152. ch = 'r';
  153. break;
  154. }
  155. fprintf (fp, ".%cvalue", ch);
  156. }
  157. /*---------------------------------------------------------------------------*/
  158. static void check_dir (int conn_number, Dir_t dir, char *context)
  159. {
  160. Dir_t conn_dir;
  161. if (conn_number >= 0) {
  162. /*
  163. * If negative, this is an invalid port ID and we've already issued
  164. * an error.
  165. */
  166. conn_dir = mod_ifs_table->conn[conn_number].direction;
  167. if ((conn_dir != dir) && (conn_dir != INOUT)) {
  168. char error_str[200];
  169. sprintf (error_str,
  170. "Direction of port `%s' in %s() is not %s or INOUT",
  171. mod_ifs_table->conn[conn_number].name, context,
  172. (dir == IN) ? "IN" : "OUT");
  173. yyerror (error_str);
  174. mod_num_errors++;
  175. }
  176. }
  177. }
  178. /*---------------------------------------------------------------------------*/
  179. static void check_subscript (Boolean_t formal, Boolean_t actual,
  180. Boolean_t missing_actual_ok,
  181. char *context, char *id)
  182. {
  183. char error_str[200];
  184. if ((formal && !actual) && !missing_actual_ok) {
  185. sprintf (error_str,
  186. "%s `%s' is an array - subscript required",
  187. context, id);
  188. yyerror (error_str);
  189. mod_num_errors++;
  190. return;
  191. } else if (!formal && actual) {
  192. sprintf (error_str,
  193. "%s `%s' is not an array - subscript prohibited",
  194. context, id);
  195. yyerror (error_str);
  196. mod_num_errors++;
  197. return;
  198. }
  199. }
  200. /*---------------------------------------------------------------------------*/
  201. static int check_id (Sub_Id_t sub_id, Id_Kind_t kind, Boolean_t do_subscript)
  202. {
  203. int i;
  204. char error_str[200];
  205. switch (kind) {
  206. case CONN:
  207. for (i = 0; i < mod_ifs_table->num_conn; i++) {
  208. if (0 == local_strcmpi (sub_id.id, mod_ifs_table->conn[i].name)) {
  209. if (do_subscript) {
  210. check_subscript (mod_ifs_table->conn[i].is_array,
  211. sub_id.has_subscript, FALSE, "Port",
  212. sub_id.id);
  213. }
  214. return i;
  215. }
  216. }
  217. break;
  218. case PARAM:
  219. for (i = 0; i < mod_ifs_table->num_param; i++) {
  220. if (0 == local_strcmpi (sub_id.id, mod_ifs_table->param[i].name)) {
  221. if (do_subscript) {
  222. check_subscript (mod_ifs_table->param[i].is_array,
  223. sub_id.has_subscript, FALSE, "Parameter",
  224. sub_id.id);
  225. }
  226. return i;
  227. }
  228. }
  229. break;
  230. case STATIC_VAR:
  231. for (i = 0; i < mod_ifs_table->num_inst_var; i++) {
  232. if (0 == local_strcmpi (sub_id.id, mod_ifs_table->inst_var[i].name)) {
  233. if (do_subscript) {
  234. check_subscript (mod_ifs_table->inst_var[i].is_array,
  235. sub_id.has_subscript, TRUE,
  236. "Static Variable",
  237. sub_id.id);
  238. }
  239. return i;
  240. }
  241. }
  242. break;
  243. }
  244. sprintf (error_str, "No %s named '%s'",
  245. ((kind==CONN)
  246. ? "port"
  247. : ((kind==PARAM)
  248. ? "parameter"
  249. :"static variable")),
  250. sub_id.id);
  251. yyerror (error_str);
  252. mod_num_errors++;
  253. return -1;
  254. }
  255. /*---------------------------------------------------------------------------*/
  256. static int valid_id (Sub_Id_t sub_id, Id_Kind_t kind)
  257. {
  258. return check_id (sub_id, kind, FALSE);
  259. }
  260. /*---------------------------------------------------------------------------*/
  261. static int valid_subid (Sub_Id_t sub_id, Id_Kind_t kind)
  262. {
  263. return check_id (sub_id, kind, TRUE);
  264. }
  265. /*---------------------------------------------------------------------------*/
  266. static void init_buffer (void)
  267. {
  268. buf_len = 0;
  269. buffer[0] = '\0';
  270. }
  271. /*---------------------------------------------------------------------------*/
  272. static void append (char *str)
  273. {
  274. int len = (int) strlen (str);
  275. if (len + buf_len > BUFFER_SIZE) {
  276. yyerror ("Buffer overflow - try reducing the complexity of CM-macro array subscripts");
  277. exit (1);
  278. }
  279. (void)strcat (buffer,str);
  280. }
  281. %}
  282. %union {
  283. char *str;
  284. Sub_Id_t sub_id;
  285. }
  286. %type <str> buffered_c_code
  287. %type <sub_id> subscriptable_id id
  288. %token TOK_ARGS
  289. %token TOK_INIT
  290. %token TOK_ANALYSIS
  291. %token TOK_NEW_TIMEPOINT
  292. %token TOK_TIME
  293. %token TOK_RAD_FREQ
  294. %token TOK_TEMPERATURE
  295. %token TOK_T
  296. %token TOK_PARAM
  297. %token TOK_PARAM_SIZE
  298. %token TOK_PARAM_NULL
  299. %token TOK_PORT_SIZE
  300. %token TOK_PORT_NULL
  301. %token TOK_PARTIAL
  302. %token TOK_AC_GAIN
  303. %token TOK_CHANGED
  304. %token TOK_OUTPUT_DELAY
  305. %token TOK_STATIC_VAR
  306. %token TOK_STATIC_VAR_SIZE
  307. %token TOK_STATIC_VAR_INST
  308. %token TOK_INPUT
  309. %token TOK_INPUT_STRENGTH
  310. %token TOK_INPUT_STATE
  311. %token TOK_INPUT_TYPE
  312. %token TOK_OUTPUT
  313. %token TOK_OUTPUT_CHANGED
  314. %token TOK_OUTPUT_STRENGTH
  315. %token TOK_OUTPUT_STATE
  316. %token TOK_OUTPUT_TYPE
  317. %token TOK_COMMA
  318. %token TOK_LPAREN
  319. %token TOK_RPAREN
  320. %token TOK_LBRACKET
  321. %token TOK_RBRACKET
  322. %token TOK_MISC_C
  323. %token TOK_IDENTIFIER
  324. %token TOK_LOAD
  325. %token TOK_TOTAL_LOAD
  326. %token TOK_MESSAGE
  327. %token TOK_CALL_TYPE
  328. %start mod_file
  329. %%
  330. mod_file : /* empty */
  331. | mod_file c_code
  332. ;
  333. c_code : /* empty */
  334. | c_code c_char
  335. | c_code macro
  336. /*| TOK_RPAREN {yyerror ("Unmatched )"); YYERROR;}
  337. | TOK_RBRACKET {yyerror ("Unmatched ]"); YYERROR;}*/
  338. ;
  339. buffered_c_code : {init_buffer();} buffered_c_code2
  340. {$$ = strdup (buffer);}
  341. ;
  342. buffered_c_code2 : /* empty */
  343. | buffered_c_code2 buffered_c_char
  344. ;
  345. buffered_c_char : TOK_IDENTIFIER {append (mod_yytext);}
  346. | TOK_MISC_C {append (mod_yytext);}
  347. | TOK_COMMA {append (mod_yytext);}
  348. | TOK_LBRACKET
  349. {append("[");}
  350. buffered_c_code2 TOK_RBRACKET
  351. {append("]");}
  352. | TOK_LPAREN
  353. {append("(");}
  354. buffered_c_code2 TOK_RPAREN
  355. {append(")");}
  356. ;
  357. c_char : TOK_IDENTIFIER {fputs (mod_yytext, mod_yyout);}
  358. | TOK_MISC_C {fputs (mod_yytext, mod_yyout);}
  359. | TOK_COMMA {fputs (mod_yytext, mod_yyout);}
  360. | TOK_LBRACKET
  361. {putc ('[', mod_yyout);}
  362. c_code TOK_RBRACKET
  363. {putc (']', mod_yyout);}
  364. | TOK_LPAREN
  365. {putc ('(', mod_yyout);}
  366. c_code TOK_RPAREN
  367. {putc (')', mod_yyout);}
  368. ;
  369. macro : TOK_INIT
  370. {fprintf (mod_yyout, "mif_private->circuit.init");}
  371. | TOK_ARGS
  372. {fprintf (mod_yyout, "Mif_Private_t *mif_private");}
  373. | TOK_ANALYSIS
  374. {fprintf (mod_yyout, "mif_private->circuit.anal_type");}
  375. | TOK_NEW_TIMEPOINT
  376. {fprintf (mod_yyout, "mif_private->circuit.anal_init");}
  377. | TOK_CALL_TYPE
  378. {fprintf (mod_yyout, "mif_private->circuit.call_type");}
  379. | TOK_TIME
  380. {fprintf (mod_yyout, "mif_private->circuit.time");}
  381. | TOK_RAD_FREQ
  382. {fprintf (mod_yyout, "mif_private->circuit.frequency");}
  383. | TOK_TEMPERATURE
  384. {fprintf (mod_yyout, "mif_private->circuit.temperature");}
  385. | TOK_T TOK_LPAREN buffered_c_code TOK_RPAREN
  386. {fprintf (mod_yyout, "mif_private->circuit.t[%s]", $3);}
  387. | TOK_PARAM TOK_LPAREN subscriptable_id TOK_RPAREN
  388. {int i = valid_subid ($3, PARAM);
  389. fprintf (mod_yyout, "mif_private->param[%d]->element[%s]",
  390. i, subscript ($3));
  391. put_type (mod_yyout, mod_ifs_table->param[i].type);
  392. }
  393. | TOK_PARAM_SIZE TOK_LPAREN id TOK_RPAREN
  394. {int i = valid_id ($3, PARAM);
  395. fprintf (mod_yyout, "mif_private->param[%d]->size", i);}
  396. | TOK_PARAM_NULL TOK_LPAREN id TOK_RPAREN
  397. {int i = valid_id ($3, PARAM);
  398. fprintf (mod_yyout, "mif_private->param[%d]->is_null", i);}
  399. | TOK_PORT_SIZE TOK_LPAREN id TOK_RPAREN
  400. {int i = valid_id ($3, CONN);
  401. fprintf (mod_yyout, "mif_private->conn[%d]->size", i);}
  402. | TOK_PORT_NULL TOK_LPAREN id TOK_RPAREN
  403. {int i = valid_id ($3, CONN);
  404. fprintf (mod_yyout, "mif_private->conn[%d]->is_null", i);}
  405. | TOK_PARTIAL TOK_LPAREN subscriptable_id TOK_COMMA
  406. subscriptable_id TOK_RPAREN
  407. {int i = valid_subid ($3, CONN);
  408. int j = valid_subid ($5, CONN);
  409. check_dir (i, OUT, "PARTIAL");
  410. check_dir (j, IN, "PARTIAL");
  411. fprintf (mod_yyout, "mif_private->conn[%d]->port[%s]->partial[%d].port[%s]",
  412. i, subscript($3), j, subscript($5));}
  413. | TOK_AC_GAIN TOK_LPAREN subscriptable_id TOK_COMMA
  414. subscriptable_id TOK_RPAREN
  415. {int i = valid_subid ($3, CONN);
  416. int j = valid_subid ($5, CONN);
  417. check_dir (i, OUT, "AC_GAIN");
  418. check_dir (j, IN, "AC_GAIN");
  419. fprintf (mod_yyout,
  420. "mif_private->conn[%d]->port[%s]->ac_gain[%d].port[%s]",
  421. i, subscript($3), j, subscript($5));}
  422. | TOK_STATIC_VAR TOK_LPAREN subscriptable_id TOK_RPAREN
  423. {int i = valid_subid ($3, STATIC_VAR);
  424. fprintf (mod_yyout,
  425. "mif_private->inst_var[%d]->element[%s]",
  426. i, subscript($3));
  427. if (mod_ifs_table->inst_var[i].is_array
  428. && !($3.has_subscript)) {
  429. /* null - eg. for malloc lvalue */
  430. } else {
  431. put_type (mod_yyout,
  432. mod_ifs_table->inst_var[i].type);
  433. } }
  434. | TOK_STATIC_VAR_SIZE TOK_LPAREN id TOK_RPAREN
  435. {int i = valid_subid ($3, STATIC_VAR);
  436. fprintf (mod_yyout, "mif_private->inst_var[%d]->size",
  437. i);}
  438. | TOK_STATIC_VAR_INST TOK_LPAREN id TOK_RPAREN
  439. {int i = valid_subid ($3, STATIC_VAR);
  440. fprintf (mod_yyout, "mif_private->inst_var[%d]",
  441. i);}
  442. | TOK_OUTPUT_DELAY TOK_LPAREN subscriptable_id TOK_RPAREN
  443. {int i = valid_subid ($3, CONN);
  444. check_dir (i, OUT, "OUTPUT_DELAY");
  445. fprintf (mod_yyout,
  446. "mif_private->conn[%d]->port[%s]->delay", i,
  447. subscript($3));}
  448. | TOK_CHANGED TOK_LPAREN subscriptable_id TOK_RPAREN
  449. {int i = valid_subid ($3, CONN);
  450. check_dir (i, OUT, "CHANGED");
  451. fprintf (mod_yyout,
  452. "mif_private->conn[%d]->port[%s]->changed", i,
  453. subscript($3));}
  454. | TOK_INPUT TOK_LPAREN subscriptable_id TOK_RPAREN
  455. {int i = valid_subid ($3, CONN);
  456. check_dir (i, IN, "INPUT");
  457. fprintf (mod_yyout,
  458. "mif_private->conn[%d]->port[%s]->input",
  459. i, subscript($3));
  460. put_conn_type (mod_yyout,
  461. mod_ifs_table->conn[i].allowed_port_type[0]);}
  462. | TOK_INPUT_TYPE TOK_LPAREN subscriptable_id TOK_RPAREN
  463. {int i = valid_subid ($3, CONN);
  464. check_dir (i, IN, "INPUT_TYPE");
  465. fprintf (mod_yyout,
  466. "mif_private->conn[%d]->port[%s]->type_str",
  467. i, subscript($3)); }
  468. | TOK_OUTPUT_TYPE TOK_LPAREN subscriptable_id TOK_RPAREN
  469. {int i = valid_subid ($3, CONN);
  470. check_dir (i, OUT, "OUTPUT_TYPE");
  471. fprintf (mod_yyout,
  472. "mif_private->conn[%d]->port[%s]->type_str",
  473. i, subscript($3)); }
  474. | TOK_INPUT_STRENGTH TOK_LPAREN subscriptable_id TOK_RPAREN
  475. {int i = valid_subid ($3, CONN);
  476. check_dir (i, IN, "INPUT_STRENGTH");
  477. fprintf (mod_yyout,
  478. "((Digital_t*)(mif_private->conn[%d]->port[%s]->input",
  479. i, subscript($3));
  480. put_conn_type (mod_yyout,
  481. mod_ifs_table->conn[i].allowed_port_type[0]);
  482. fprintf (mod_yyout, "))->strength");}
  483. | TOK_INPUT_STATE TOK_LPAREN subscriptable_id TOK_RPAREN
  484. {int i = valid_subid ($3, CONN);
  485. check_dir (i, IN, "INPUT_STATE");
  486. fprintf (mod_yyout,
  487. "((Digital_t*)(mif_private->conn[%d]->port[%s]->input",
  488. i, subscript($3));
  489. put_conn_type (mod_yyout,
  490. mod_ifs_table->conn[i].allowed_port_type[0]);
  491. fprintf (mod_yyout, "))->state");}
  492. | TOK_OUTPUT TOK_LPAREN subscriptable_id TOK_RPAREN
  493. {int i = valid_subid ($3, CONN);
  494. check_dir (i, OUT, "OUTPUT");
  495. fprintf (mod_yyout,
  496. "mif_private->conn[%d]->port[%s]->output",
  497. i, subscript($3));
  498. put_conn_type (mod_yyout,
  499. mod_ifs_table->conn[i].allowed_port_type[0]);}
  500. | TOK_OUTPUT_STRENGTH TOK_LPAREN subscriptable_id TOK_RPAREN
  501. {int i = valid_subid ($3, CONN);
  502. check_dir (i, OUT, "OUTPUT_STRENGTH");
  503. fprintf (mod_yyout,
  504. "((Digital_t*)(mif_private->conn[%d]->port[%s]->output",
  505. i, subscript($3));
  506. put_conn_type (mod_yyout,
  507. mod_ifs_table->conn[i].allowed_port_type[0]);
  508. fprintf (mod_yyout, "))->strength");}
  509. | TOK_OUTPUT_STATE TOK_LPAREN subscriptable_id TOK_RPAREN
  510. {int i = valid_subid ($3, CONN);
  511. check_dir (i, OUT, "OUTPUT_STATE");
  512. fprintf (mod_yyout,
  513. "((Digital_t*)(mif_private->conn[%d]->port[%s]->output",
  514. i, subscript($3));
  515. put_conn_type (mod_yyout,
  516. mod_ifs_table->conn[i].allowed_port_type[0]);
  517. fprintf (mod_yyout, "))->state");}
  518. | TOK_OUTPUT_CHANGED TOK_LPAREN subscriptable_id TOK_RPAREN
  519. {int i = valid_subid ($3, CONN);
  520. fprintf (mod_yyout,
  521. "mif_private->conn[%d]->port[%s]->changed", i,
  522. subscript($3));}
  523. | TOK_LOAD TOK_LPAREN subscriptable_id TOK_RPAREN
  524. {int i = valid_subid ($3, CONN);
  525. fprintf (mod_yyout,
  526. "mif_private->conn[%d]->port[%s]->load", i,
  527. subscript($3));}
  528. | TOK_TOTAL_LOAD TOK_LPAREN subscriptable_id TOK_RPAREN
  529. {int i = valid_subid ($3, CONN);
  530. fprintf (mod_yyout,
  531. "mif_private->conn[%d]->port[%s]->total_load", i,
  532. subscript($3));}
  533. | TOK_MESSAGE TOK_LPAREN subscriptable_id TOK_RPAREN
  534. {int i = valid_subid ($3, CONN);
  535. fprintf (mod_yyout,
  536. "mif_private->conn[%d]->port[%s]->msg", i,
  537. subscript($3));}
  538. ;
  539. subscriptable_id : id
  540. | id TOK_LBRACKET buffered_c_code TOK_RBRACKET
  541. {$$ = $1;
  542. $$.has_subscript = TRUE;
  543. $$.subscript = $3;}
  544. ;
  545. id : TOK_IDENTIFIER
  546. {$$.has_subscript = FALSE;
  547. $$.id = strdup (mod_yytext);}
  548. ;
  549. %%