diff lwcc/parse_c.y @ 495:5b8871fd7503

Merged previous lwcc development branch into mainline.
author William Astle <lost@l-w.ca>
date Mon, 05 Aug 2019 21:27:09 -0600
parents a3e277c58df9
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwcc/parse_c.y	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,97 @@
+%include {
+#include <assert.h> // only needed due to a bug in lemon
+#include <stdio.h>
+#include "parse.h"
+#include "tree.h"
+}
+
+%token_type { struct tokendata * }
+%token_prefix PTOK_
+%token_destructor { tokendata_free($$); }
+%default_type { node_t * }
+%extra_argument { struct parserinfo *pinfo }
+
+program(A) ::= rprogram(B). { A = B; pinfo -> parsetree = A; }
+
+rprogram(A) ::= rprogram(C) globaldecl(B). {
+	A = C;
+	node_addchild(A, B);
+}
+rprogram(A) ::= . { A = node_create(NODE_PROGRAM); }
+
+globaldecl(A) ::= vardecl(B). { A = B; }
+globaldecl(A) ::= fundecl(B). { A = B; }
+
+vardecl(A) ::= datatype(B) ident(C) ENDS. {
+	A = node_create(NODE_DECL, B, C);
+}
+
+ident(A) ::= IDENTIFIER(B). { A = node_create(NODE_IDENT, B -> strval); }
+
+datatype(A) ::= typename(B). { A = B; }
+datatype(A) ::= datatype(B) STAR. { A = node_create(NODE_TYPE_PTR, B); }
+
+typename(A) ::= KW_VOID. { A = node_create(NODE_TYPE_VOID); }
+typename(A) ::= KW_FLOAT. { A = node_create(NODE_TYPE_FLOAT); }
+typename(A) ::= KW_DOUBLE. { A = node_create(NODE_TYPE_DOUBLE); }
+typename(A) ::= KW_LONG KW_DOUBLE. { A = node_create(NODE_TYPE_LDOUBLE); }
+typename(A) ::= baseint(B). { A = B; }
+typename(A) ::= KW_UNSIGNED. { A = node_create(NODE_TYPE_UINT); }
+typename(A) ::= KW_SIGNED. { A = node_create(NODE_TYPE_INT); }
+typename(A) ::= KW_SIGNED baseint(B). { A = B; if (A -> type == NODE_TYPE_CHAR) A -> type = NODE_TYPE_SCHAR; }
+typename(A) ::= KW_UNSIGNED baseint(B). {
+	A = B;
+	switch (A -> type)
+	{
+	case NODE_TYPE_CHAR:
+		A -> type = NODE_TYPE_UCHAR;
+		break;
+	case NODE_TYPE_SHORT:
+		A -> type = NODE_TYPE_USHORT;
+		break;
+	case NODE_TYPE_INT:
+		A -> type = NODE_TYPE_UINT;
+		break;
+	case NODE_TYPE_LONG:
+		A -> type = NODE_TYPE_ULONG;
+		break;
+	case NODE_TYPE_LONGLONG:
+		A -> type = NODE_TYPE_ULONGLONG;
+		break;
+	}
+}
+
+baseint(A) ::= KW_INT. { A = node_create(NODE_TYPE_INT); } 
+baseint(A) ::= KW_LONG. { A = node_create(NODE_TYPE_LONG); }
+baseint(A) ::= KW_LONG KW_INT. { A = node_create(NODE_TYPE_LONG); }
+baseint(A) ::= KW_LONG KW_LONG. { A = node_create(NODE_TYPE_LONGLONG); }
+baseint(A) ::= KW_SHORT. { A = node_create(NODE_TYPE_SHORT); }
+baseint(A) ::= KW_LONG KW_LONG KW_INT. { A = node_create(NODE_TYPE_LONGLONG); }
+baseint(A) ::= KW_SHORT KW_INT. { A = node_create(NODE_TYPE_SHORT); }
+baseint(A) ::= KW_CHAR. { A = node_create(NODE_TYPE_CHAR); }
+
+
+fundecl(A) ::= datatype(B) ident(C) arglist(D) statementblock(E). {
+	A = node_create(NODE_FUNDEF, B, C, D, E);
+}
+
+fundecl(A) ::= datatype(B) ident(C) arglist(D) ENDS. {
+	A = node_create(NODE_FUNDECL, B, C, D);
+}
+
+arglist(A) ::= OPAREN CPAREN. { A = node_create(NODE_FUNARGS); }
+
+statementblock(A) ::= OBRACE CBRACE. { A = node_create(NODE_BLOCK); }
+
+%parse_failure {
+	fprintf(stderr, "Parse error\n");
+}
+
+%stack_overflow {
+	fprintf(stderr, "Parser stack overflow\n");
+}
+
+%syntax_error {
+	fprintf(stderr, "Undexpected token %d: ", TOKEN -> tokid);
+	tokendata_print(stderr, TOKEN);
+}