parse_c.sh
上传用户:gerber99
上传日期:2007-01-06
资源大小:5k
文件大小:14k
源码类别:

编译器/解释器

开发平台:

C/C++

  1. #!/bin/sh
  2. # This is a shell archive, meaning:
  3. # 1. Remove everything above the #!/bin/sh line.
  4. # 2. Save the resulting text in a file.
  5. # 3. Execute the file with /bin/sh (not csh) to create the files:
  6. # README
  7. # Makefile
  8. # gram.y
  9. # scan.l
  10. # main.c
  11. # This archive created: Fri May 10 13:51:08 1985
  12. # By: Arnold Robbins (Pr1mebusters!)
  13. export PATH; PATH=/bin:$PATH
  14. echo shar: extracting "'README'" '(1419 characters)'
  15. if test -f 'README'
  16. then
  17. echo shar: over-writing existing file "'README'"
  18. fi
  19. cat << SHAR_EOF > 'README'
  20. The files in this directory contain the ANSI C grammar from the Nov 12, 1984
  21. draft of the standard.  Note that a newer draft has come out since then.
  22. I have applied the two bug fixes I have seen reported on the net for this
  23. grammar.
  24. With a little work, this grammar can be made to parse regular C.
  25. I am reposting it, due to popular demand.  Credit for creating this in
  26. the first place goes to my office mate, Jeff Lee, gatech!jeff.
  27. Here is his original note:
  28. > This is the current (Nov 12, 1984) draft of the C grammar in Yacc form
  29. > with a little scanner I wrote in Lex so that you end up with a complete
  30. > program with which you can amaze and befuddle your friends. Or you can
  31. > sit and crank your own output through it to amuse yourself if you have the
  32. > personality of a cumquat(sp?). This contains nothing to handle preprocessor
  33. > stuff nor to handle "#line" directives so you must remove these beforehand
  34. > to allow it to parse the stuff. Also, it bypasses the typedef problem
  35. > by always returning an IDENTIFIER when it encounters anything that looks
  36. > like an IDENTIFIER, but it has a little stub in place where you would put
  37. > your symbol table lookup to determine if it a typedef or not. Other than
  38. > that, this is all yours. Wear it in good health and if anyone asks, just say
  39. > I told you so. Oh, by the way..... this is in 'shar' format, so you know
  40. > what to do.
  41. Arnold Robbins
  42. gatech!arnold
  43. May, 1985
  44. SHAR_EOF
  45. echo shar: extracting "'Makefile'" '(167 characters)'
  46. if test -f 'Makefile'
  47. then
  48. echo shar: over-writing existing file "'Makefile'"
  49. fi
  50. cat << SHAR_EOF > 'Makefile'
  51. YFLAGS = -d
  52. CFLAGS = -O
  53. LFLAGS =
  54. SRC = gram.y scan.l main.c
  55. OBJ = gram.o scan.o main.o
  56. a.out : $(OBJ)
  57. cc $(OBJ)
  58. scan.o : y.tab.h
  59. clean :
  60. rm -f a.out y.tab.h *.o
  61. SHAR_EOF
  62. echo shar: extracting "'gram.y'" '(7344 characters)'
  63. if test -f 'gram.y'
  64. then
  65. echo shar: over-writing existing file "'gram.y'"
  66. fi
  67. cat << SHAR_EOF > 'gram.y'
  68. %token IDENTIFIER CONSTANT STRING_LITERAL SIZEOF
  69. %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
  70. %token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
  71. %token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
  72. %token XOR_ASSIGN OR_ASSIGN TYPE_NAME
  73. %token TYPEDEF EXTERN STATIC AUTO REGISTER
  74. %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID
  75. %token STRUCT UNION ENUM ELIPSIS RANGE
  76. %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
  77. %start file
  78. %%
  79. primary_expr
  80. : identifier
  81. | CONSTANT
  82. | STRING_LITERAL
  83. | '(' expr ')'
  84. | primary_expr '[' expr ']'
  85. | primary_expr '(' ')'
  86. | primary_expr '(' argument_expr_list ')'
  87. | primary_expr '.' identifier
  88. | primary_expr PTR_OP identifier
  89. ;
  90. argument_expr_list
  91. : assignment_expr
  92. | argument_expr_list ',' assignment_expr
  93. ;
  94. postfix_expr
  95. : primary_expr
  96. | primary_expr INC_OP
  97. | primary_expr DEC_OP
  98. ;
  99. unary_expr
  100. : postfix_expr
  101. | INC_OP unary_expr
  102. | DEC_OP unary_expr
  103. | unary_operator cast_expr
  104. | SIZEOF unary_expr
  105. | SIZEOF '(' type_name ')'
  106. ;
  107. unary_operator
  108. : '&'
  109. | '*'
  110. | '+'
  111. | '-'
  112. | '~'
  113. | '!'
  114. ;
  115. cast_expr
  116. : unary_expr
  117. | '(' type_name ')' cast_expr
  118. ;
  119. multiplicative_expr
  120. : cast_expr
  121. | multiplicative_expr '*' cast_expr
  122. | multiplicative_expr '/' cast_expr
  123. | multiplicative_expr '%' cast_expr
  124. ;
  125. additive_expr
  126. : multiplicative_expr
  127. | additive_expr '+' multiplicative_expr
  128. | additive_expr '-' multiplicative_expr
  129. ;
  130. shift_expr
  131. : additive_expr
  132. | shift_expr LEFT_OP additive_expr
  133. | shift_expr RIGHT_OP additive_expr
  134. ;
  135. relational_expr
  136. : shift_expr
  137. | relational_expr '<' shift_expr
  138. | relational_expr '>' shift_expr
  139. | relational_expr LE_OP shift_expr
  140. | relational_expr GE_OP shift_expr
  141. ;
  142. equality_expr
  143. : relational_expr
  144. | equality_expr EQ_OP relational_expr
  145. | equality_expr NE_OP relational_expr
  146. ;
  147. and_expr
  148. : equality_expr
  149. | and_expr '&' equality_expr
  150. ;
  151. exclusive_or_expr
  152. : and_expr
  153. | exclusive_or_expr '^' and_expr
  154. ;
  155. inclusive_or_expr
  156. : exclusive_or_expr
  157. | inclusive_or_expr '|' exclusive_or_expr
  158. ;
  159. logical_and_expr
  160. : inclusive_or_expr
  161. | logical_and_expr AND_OP inclusive_or_expr
  162. ;
  163. logical_or_expr
  164. : logical_and_expr
  165. | logical_or_expr OR_OP logical_and_expr
  166. ;
  167. conditional_expr
  168. : logical_or_expr
  169. | logical_or_expr '?' logical_or_expr ':' conditional_expr
  170. ;
  171. assignment_expr
  172. : conditional_expr
  173. | unary_expr assignment_operator assignment_expr
  174. ;
  175. assignment_operator
  176. : '='
  177. | MUL_ASSIGN
  178. | DIV_ASSIGN
  179. | MOD_ASSIGN
  180. | ADD_ASSIGN
  181. | SUB_ASSIGN
  182. | LEFT_ASSIGN
  183. | RIGHT_ASSIGN
  184. | AND_ASSIGN
  185. | XOR_ASSIGN
  186. | OR_ASSIGN
  187. ;
  188. expr
  189. : assignment_expr
  190. | expr ',' assignment_expr
  191. ;
  192. constant_expr
  193. : conditional_expr
  194. ;
  195. declaration
  196. : declaration_specifiers ';'
  197. | declaration_specifiers init_declarator_list ';'
  198. ;
  199. declaration_specifiers
  200. : ssc_specifier
  201. | ssc_specifier declaration_specifiers
  202. | type_specifier
  203. | type_specifier declaration_specifiers
  204. ;
  205. init_declarator_list
  206. : init_declarator
  207. | init_declarator_list ',' init_declarator
  208. ;
  209. init_declarator
  210. : declarator
  211. | declarator '=' initializer
  212. ;
  213. ssc_specifier
  214. : TYPEDEF
  215. | EXTERN
  216. | STATIC
  217. | AUTO
  218. | REGISTER
  219. ;
  220. type_specifier
  221. : CHAR
  222. | SHORT
  223. | INT
  224. | LONG
  225. | SIGNED
  226. | UNSIGNED
  227. | FLOAT
  228. | DOUBLE
  229. | CONST
  230. | VOLATILE
  231. | VOID
  232. | struct_or_union_specifier
  233. | enum_specifier
  234. | TYPE_NAME
  235. ;
  236. struct_or_union_specifier
  237. : struct_or_union identifier '{' struct_declaration_list '}'
  238. | struct_or_union '{' struct_declaration_list '}'
  239. | struct_or_union identifier
  240. ;
  241. struct_or_union
  242. : STRUCT
  243. | UNION
  244. ;
  245. struct_declaration_list
  246. : struct_declaration
  247. | struct_declaration_list struct_declaration
  248. ;
  249. struct_declaration
  250. : type_specifier_list struct_declarator_list ';'
  251. ;
  252. struct_declarator_list
  253. : struct_declarator
  254. | struct_declarator_list ',' struct_declarator
  255. ;
  256. struct_declarator
  257. : declarator
  258. | ':' constant_expr
  259. | declarator ':' constant_expr
  260. ;
  261. enum_specifier
  262. : ENUM '{' enumerator_list '}'
  263. | ENUM identifier '{' enumerator_list '}'
  264. | ENUM identifier
  265. ;
  266. enumerator_list
  267. : enumerator
  268. | enumerator_list ',' enumerator
  269. ;
  270. enumerator
  271. : identifier
  272. | identifier '=' constant_expr
  273. ;
  274. declarator
  275. : declarator2
  276. | pointer declarator2
  277. ;
  278. declarator2
  279. : identifier
  280. | '(' declarator ')'
  281. | declarator2 '[' ']'
  282. | declarator2 '[' constant_expr ']'
  283. | declarator2 '(' ')'
  284. | declarator2 '(' parameter_declaration_list ')'
  285. ;
  286. pointer
  287. : '*'
  288. | '*' type_specifier_list
  289. | '*' pointer
  290. | '*' type_specifier_list pointer
  291. ;
  292. type_specifier_list
  293. : type_specifier
  294. | type_specifier_list type_specifier
  295. ;
  296. parameter_declaration_list
  297. : identifier_list
  298. | identifier_list ',' ELIPSIS
  299. | parameter_types
  300. ;
  301. identifier_list
  302. : identifier
  303. | identifier_list ',' identifier
  304. ;
  305. parameter_types
  306. : parameter_list
  307. | parameter_list ',' ELIPSIS
  308. ;
  309. parameter_list
  310. : parameter_declaration
  311. | parameter_list ',' parameter_declaration
  312. ;
  313. parameter_declaration
  314. : type_specifier_list declarator
  315. | type_name
  316. ;
  317. type_name
  318. : type_specifier_list
  319. | type_specifier_list abstract_declarator
  320. ;
  321. abstract_declarator
  322. : pointer
  323. | abstract_declarator2
  324. | pointer abstract_declarator2
  325. ;
  326. abstract_declarator2
  327. : '(' abstract_declarator ')'
  328. | '[' ']'
  329. | '[' constant_expr ']'
  330. | abstract_declarator2 '[' ']'
  331. | abstract_declarator2 '[' constant_expr ']'
  332. | '(' ')'
  333. | '(' parameter_types ')'
  334. | abstract_declarator2 '(' ')'
  335. | abstract_declarator2 '(' parameter_types ')'
  336. ;
  337. initializer
  338. : assignment_expr
  339. | '{' initializer_list '}'
  340. | '{' initializer_list ',' '}'
  341. ;
  342. initializer_list
  343. : initializer
  344. | initializer_list ',' initializer
  345. ;
  346. statement
  347. : labeled_statement
  348. | compound_statement
  349. | expression_statement
  350. | selection_statement
  351. | iteration_statement
  352. | jump_statement
  353. ;
  354. labeled_statement
  355. : identifier ':' statement
  356. | CASE constant_expr ':' statement
  357. | CASE constant_expr RANGE constant_expr ':' statement
  358. | DEFAULT ':' statement
  359. ;
  360. compound_statement
  361. : '{' '}'
  362. | '{' statement_list '}'
  363. | '{' declaration_list '}'
  364. | '{' declaration_list statement_list '}'
  365. ;
  366. declaration_list
  367. : declaration
  368. | declaration_list declaration
  369. ;
  370. statement_list
  371. : statement
  372. | statement_list statement
  373. ;
  374. expression_statement
  375. : ';'
  376. | expr ';'
  377. ;
  378. selection_statement
  379. : IF '(' expr ')' statement
  380. | IF '(' expr ')' statement ELSE statement
  381. | SWITCH '(' expr ')' statement
  382. ;
  383. iteration_statement
  384. : WHILE '(' expr ')' statement
  385. | DO statement WHILE '(' expr ')' ';'
  386. | FOR '(' ';' ';' ')' statement
  387. | FOR '(' ';' ';' expr ')' statement
  388. | FOR '(' ';' expr ';' ')' statement
  389. | FOR '(' ';' expr ';' expr ')' statement
  390. | FOR '(' expr ';' ';' ')' statement
  391. | FOR '(' expr ';' ';' expr ')' statement
  392. | FOR '(' expr ';' expr ';' ')' statement
  393. | FOR '(' expr ';' expr ';' expr ')' statement
  394. ;
  395. jump_statement
  396. : GOTO identifier ';'
  397. | CONTINUE ';'
  398. | BREAK ';'
  399. | RETURN ';'
  400. | RETURN expr ';'
  401. ;
  402. file
  403. : external_definition
  404. | file external_definition
  405. ;
  406. external_definition
  407. : function_definition
  408. | declaration
  409. ;
  410. function_definition
  411. : declarator function_body
  412. | declaration_specifiers declarator function_body
  413. ;
  414. function_body
  415. : compound_statement
  416. | declaration_list compound_statement
  417. ;
  418. identifier
  419. : IDENTIFIER
  420. ;
  421. %%
  422. #include <stdio.h>
  423. extern char *yytext;
  424. extern int column;
  425. yyerror(s)
  426. char *s;
  427. {
  428. fflush(stdout);
  429. printf("n%*sn%*sn", column, "^", column, s);
  430. }
  431. SHAR_EOF
  432. echo shar: extracting "'scan.l'" '(4263 characters)'
  433. if test -f 'scan.l'
  434. then
  435. echo shar: over-writing existing file "'scan.l'"
  436. fi
  437. cat << SHAR_EOF > 'scan.l'
  438. D [0-9]
  439. L [a-zA-Z_]
  440. H [a-fA-F0-9]
  441. E [Ee][+-]?{D}+
  442. LS (l|L)
  443. US (u|U)
  444. %{
  445. #include <stdio.h>
  446. #include "y.tab.h"
  447. void count();
  448. %}
  449. %%
  450. "/*" { comment(); }
  451. "auto" { count(); return(AUTO); }
  452. "break" { count(); return(BREAK); }
  453. "case" { count(); return(CASE); }
  454. "char" { count(); return(CHAR); }
  455. "const" { count(); return(CONST); }
  456. "continue" { count(); return(CONTINUE); }
  457. "default" { count(); return(DEFAULT); }
  458. "do" { count(); return(DO); }
  459. "double" { count(); return(DOUBLE); }
  460. "else" { count(); return(ELSE); }
  461. "enum" { count(); return(ENUM); }
  462. "extern" { count(); return(EXTERN); }
  463. "float" { count(); return(FLOAT); }
  464. "for" { count(); return(FOR); }
  465. "goto" { count(); return(GOTO); }
  466. "if" { count(); return(IF); }
  467. "int" { count(); return(INT); }
  468. "long" { count(); return(LONG); }
  469. "register" { count(); return(REGISTER); }
  470. "return" { count(); return(RETURN); }
  471. "short" { count(); return(SHORT); }
  472. "signed" { count(); return(SIGNED); }
  473. "sizeof" { count(); return(SIZEOF); }
  474. "static" { count(); return(STATIC); }
  475. "struct" { count(); return(STRUCT); }
  476. "switch" { count(); return(SWITCH); }
  477. "typedef" { count(); return(TYPEDEF); }
  478. "union" { count(); return(UNION); }
  479. "unsigned" { count(); return(UNSIGNED); }
  480. "void" { count(); return(VOID); }
  481. "volatile" { count(); return(VOLATILE); }
  482. "while" { count(); return(WHILE); }
  483. {L}({L}|{D})* { count(); return(check_type()); }
  484. 0[xX]{H}+{LS}?{US}? { count(); return(CONSTANT); }
  485. 0[xX]{H}+{US}?{LS}? { count(); return(CONSTANT); }
  486. 0{D}+{LS}?{US}? { count(); return(CONSTANT); }
  487. 0{D}+{US}?{LS}? { count(); return(CONSTANT); }
  488. {D}+{LS}?{US}? { count(); return(CONSTANT); }
  489. {D}+{US}?{LS}? { count(); return(CONSTANT); }
  490. '(\.|[^\'])+' { count(); return(CONSTANT); }
  491. {D}+{E}{LS}? { count(); return(CONSTANT); }
  492. {D}*"."{D}+({E})?{LS}? { count(); return(CONSTANT); }
  493. {D}+"."{D}*({E})?{LS}? { count(); return(CONSTANT); }
  494. "(\.|[^\"])*" { count(); return(STRING_LITERAL); }
  495. ">>=" { count(); return(RIGHT_ASSIGN); }
  496. "<<=" { count(); return(LEFT_ASSIGN); }
  497. "+=" { count(); return(ADD_ASSIGN); }
  498. "-=" { count(); return(SUB_ASSIGN); }
  499. "*=" { count(); return(MUL_ASSIGN); }
  500. "/=" { count(); return(DIV_ASSIGN); }
  501. "%=" { count(); return(MOD_ASSIGN); }
  502. "&=" { count(); return(AND_ASSIGN); }
  503. "^=" { count(); return(XOR_ASSIGN); }
  504. "|=" { count(); return(OR_ASSIGN); }
  505. ">>" { count(); return(RIGHT_OP); }
  506. "<<" { count(); return(LEFT_OP); }
  507. "++" { count(); return(INC_OP); }
  508. "--" { count(); return(DEC_OP); }
  509. "->" { count(); return(PTR_OP); }
  510. "&&" { count(); return(AND_OP); }
  511. "||" { count(); return(OR_OP); }
  512. "<=" { count(); return(LE_OP); }
  513. ">=" { count(); return(GE_OP); }
  514. "==" { count(); return(EQ_OP); }
  515. "!=" { count(); return(NE_OP); }
  516. ";" { count(); return(';'); }
  517. "{" { count(); return('{'); }
  518. "}" { count(); return('}'); }
  519. "," { count(); return(','); }
  520. ":" { count(); return(':'); }
  521. "=" { count(); return('='); }
  522. "(" { count(); return('('); }
  523. ")" { count(); return(')'); }
  524. "[" { count(); return('['); }
  525. "]" { count(); return(']'); }
  526. "." { count(); return('.'); }
  527. "&" { count(); return('&'); }
  528. "!" { count(); return('!'); }
  529. "~" { count(); return('~'); }
  530. "-" { count(); return('-'); }
  531. "+" { count(); return('+'); }
  532. "*" { count(); return('*'); }
  533. "/" { count(); return('/'); }
  534. "%" { count(); return('%'); }
  535. "<" { count(); return('<'); }
  536. ">" { count(); return('>'); }
  537. "^" { count(); return('^'); }
  538. "|" { count(); return('|'); }
  539. "?" { count(); return('?'); }
  540. [ tvnf] { count(); }
  541. . { /* ignore bad characters */ }
  542. %%
  543. yywrap()
  544. {
  545. return(1);
  546. }
  547. comment()
  548. {
  549. char c, c1;
  550. loop:
  551. while ((c = input()) != '*' && c != 0)
  552. putchar(c);
  553. if ((c1 = input()) != '/' && c != 0)
  554. {
  555. unput(c1);
  556. goto loop;
  557. }
  558. if (c != 0)
  559. putchar(c1);
  560. }
  561. int column = 0;
  562. void count()
  563. {
  564. int i;
  565. for (i = 0; yytext[i] != ''; i++)
  566. if (yytext[i] == 'n')
  567. column = 0;
  568. else if (yytext[i] == 't')
  569. column += 8 - (column % 8);
  570. else
  571. column++;
  572. ECHO;
  573. }
  574. int check_type()
  575. {
  576. /*
  577. * pseudo code --- this is what it should check
  578. *
  579. * if (yytext == type_name)
  580. * return(TYPE_NAME);
  581. *
  582. * return(IDENTIFIER);
  583. */
  584. /*
  585. * it actually will only return IDENTIFIER
  586. */
  587. return(IDENTIFIER);
  588. }
  589. SHAR_EOF
  590. echo shar: extracting "'main.c'" '(48 characters)'
  591. if test -f 'main.c'
  592. then
  593. echo shar: over-writing existing file "'main.c'"
  594. fi
  595. cat << SHAR_EOF > 'main.c'
  596. main()
  597. {
  598. int yyparse();
  599. return(yyparse());
  600. }
  601. SHAR_EOF
  602. # End of shell archive
  603. exit 0