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