1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "ex0_wrapper.h"
4 #include "ex0_lexer.h"
5 #include "ex0_parse.h"
6 #include "../lib/mlrutil.h"
7 #include "./ex_ast.h"
8 #include "../containers/sllv.h"
9
10 // These prototypes are copied out manually from ex0_parse.c. With some
11 // more work I could have Lemon autogenerate these prototypes into
12 // ex0_parse.h.
13
14 void *ex0_lemon_parser_alloc(void *(*mallocProc)(size_t));
15
16 int ex0_lemon_parser_parse_token(
17 void *pvparser, /* The parser */
18 int yymajor, /* The major token code number */
19 ex_ast_node_t* yyminor, /* The value for the token */
20 ex_ast_t* past); /* Optional %extra_argument parameter */
21 void ex0_lemon_parser_free(
22 void *pvparser, /* The parser to be deleted */
23 void (*freeProc)(void*)); /* Function used to reclaim memory */
24
25 void ex0_ParseTrace(FILE *TraceFILE, char *zTracePrompt);
26
27 // ----------------------------------------------------------------
28 // http://flex.sourceforge.net/manual/Init-and-Destroy-Functions.html
29 // http://flex.sourceforge.net/manual/Extra-Data.html
30
31 // Returns linked list of ex_ast_node_t*.
ex0_parse_inner(yyscan_t scanner,void * pvparser,ex_ast_node_t ** ppnode,int trace_parse)32 static ex_ast_t* ex0_parse_inner(yyscan_t scanner, void* pvparser, ex_ast_node_t** ppnode,
33 int trace_parse)
34 {
35 int lex_code;
36 int parse_code;
37 ex_ast_t* past = ex_ast_alloc();
38 if (trace_parse)
39 ex0_ParseTrace(stderr, "[DSLTRACE] ");
40 do {
41 lex_code = ex0_lexer_lex(scanner);
42 ex_ast_node_t* plexed_node = *ppnode;
43 parse_code = ex0_lemon_parser_parse_token(pvparser, lex_code, plexed_node, past);
44 if (parse_code == 0) {
45 return NULL;
46 }
47 } while (lex_code > 0);
48 if (-1 == lex_code) {
49 fprintf(stderr, "The scanner encountered an error.\n");
50 return NULL;
51 }
52 parse_code = ex0_lemon_parser_parse_token(pvparser, 0, NULL, past);
53
54 if (parse_code == 0)
55 return NULL;
56 return past;
57 }
58
59 // ----------------------------------------------------------------
60 // Returns linked list of ex_ast_node_t*.
ex0_parse(char * string,int trace_parse)61 ex_ast_t* ex0_parse(char* string, int trace_parse) {
62 ex_ast_node_t* pnode = NULL;
63 yyscan_t scanner;
64 ex0_lexer_lex_init_extra(&pnode, &scanner);
65 void* pvparser = ex0_lemon_parser_alloc(malloc);
66
67 YY_BUFFER_STATE buf = NULL;
68 if (string == NULL) {
69 ex0_lexer_set_in(stdin, scanner);
70 } else {
71 YY_BUFFER_STATE buf = ex0_lexer__scan_string(string, scanner);
72 ex0_lexer__switch_to_buffer (buf, scanner);
73 }
74
75 ex_ast_t* past = ex0_parse_inner(scanner, pvparser, &pnode, trace_parse);
76
77 if (buf != NULL)
78 ex0_lexer__delete_buffer(buf, scanner);
79
80 ex0_lexer_lex_destroy(scanner);
81 ex0_lemon_parser_free(pvparser, free);
82
83 return past;
84 }
85
86 // ----------------------------------------------------------------
yytestcase(int ignored)87 void yytestcase(int ignored) {
88 }
89
90 // ----------------------------------------------------------------
main(int argc,char ** argv)91 int main(int argc, char** argv) {
92 int trace_parse = FALSE;
93 int argi = 1;
94 if (argc >= 2 && streq(argv[1], "-t")) {
95 argi++;
96 trace_parse = TRUE;
97 }
98 if ((argc - argi) != 1) {
99 fprintf(stderr, "Usage: %s [-t] {expression}\n", argv[0]);
100 exit(1);
101 }
102
103 ex_ast_t* past = ex0_parse(argv[argi], trace_parse);
104 if (past == NULL) {
105 printf("syntax error\n");
106 } else {
107 ex_ast_print(past);
108 }
109
110 return 0;
111 }
112