peephole.y 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. %{
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. // Instruction types
  5. #define TYPE_COMMENT 0
  6. #define TYPE_INLINE_COMMENT 1
  7. #define TYPE_DIRECTIVE 2
  8. #define TYPE_LABEL 3
  9. #define TYPE_CMD 4
  10. typedef struct line {
  11. // Type:
  12. int type;
  13. char *name;
  14. int argc;
  15. char **argv;
  16. struct line *next;
  17. } line;
  18. void yyerror(char *error);
  19. extern int yylex(void);
  20. void add_line(int type, char *name, int argc, char **argv);
  21. char **malloc_args(int argc);
  22. line *first_line, *last_line;
  23. int lineno = 0;
  24. %}
  25. %union {
  26. char *sval;
  27. }
  28. %token <sval> COMMENT DIRECTIVE WORD
  29. %token NEWLINE COMMA COLON
  30. %%
  31. input:
  32. /* Empty */
  33. | input line
  34. ;
  35. line:
  36. NEWLINE
  37. | COMMENT NEWLINE { add_line(TYPE_COMMENT, $1, 0, NULL); }
  38. | instruction NEWLINE
  39. | instruction COMMENT NEWLINE { add_line(TYPE_INLINE_COMMENT, $2, 0, NULL); }
  40. ;
  41. instruction:
  42. command
  43. | DIRECTIVE { add_line(TYPE_DIRECTIVE, $1, 0, NULL); }
  44. | WORD COLON { add_line(TYPE_LABEL, $1, 0, NULL); }
  45. | error
  46. ;
  47. command:
  48. WORD WORD COMMA WORD COMMA WORD {
  49. char **argv = malloc_args(3);
  50. argv[0] = $2;
  51. argv[1] = $4;
  52. argv[2] = $6;
  53. add_line(TYPE_CMD, $1, 3, argv);
  54. }
  55. | WORD WORD COMMA WORD {
  56. char **argv = malloc_args(2);
  57. argv[0] = $2;
  58. argv[1] = $4;
  59. add_line(TYPE_CMD, $1, 2, argv);
  60. }
  61. | WORD WORD {
  62. char **argv = malloc_args(1);
  63. argv[0] = $2;
  64. add_line(TYPE_CMD, $1, 1, argv);
  65. }
  66. ;
  67. %%
  68. extern int yylex();
  69. extern int yyparse();
  70. extern FILE *yyin;
  71. /*int main(void) {
  72. return yyparse();
  73. }*/
  74. int main(int argc, const char *argv[]) {
  75. if( argc < 2 ) {
  76. printf("No file specified");
  77. exit(-1);
  78. }
  79. // open a file handle to a particular file:
  80. FILE *myfile = fopen(argv[1], "r");
  81. // make sure it is valid:
  82. if( !myfile ) {
  83. printf("Cannot open %s\n", argv[1]);
  84. return -1;
  85. }
  86. // set lex to read from it instead of defaulting to STDIN:
  87. yyin = myfile;
  88. // parse through the input until there is no more:
  89. do {
  90. yyparse();
  91. } while( !feof(yyin) );
  92. }
  93. void yyerror(char *error) {
  94. fprintf(stderr, "Error at line %d: %s\n", lineno, error);
  95. }
  96. void add_line(int type, char *name, int argc, char **argv) {
  97. line *l = (line*)malloc(sizeof(line));
  98. printf("%d: %s\n", lineno, name);
  99. l->argc = argc;
  100. l->argv = argv;
  101. if( last_line == NULL ) {
  102. // First line
  103. first_line = last_line = l;
  104. } else {
  105. // Add line to linked list
  106. last_line = last_line->next = l;
  107. }
  108. }
  109. char **malloc_args(int argc) {
  110. return (char **)malloc(3 * sizeof(char *));
  111. }