aboutsummaryrefslogtreecommitdiff
path: root/parser.y
blob: 9a94480b95c358c323f5953b53cc0df77657390c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
%{
#include <stdio.h>
#include "ast.h"

extern char *yytext;
extern int yylineno;
extern int yylex();

ASTNode *ast_root;

void yyerror(const char *s) { 
  fprintf(stderr, "Parse error at token \"%s\", line %d: %s\n", yytext, yylineno, s); 
}
%}


%union {
  int            num;
  char           *id;
  int            op;
  struct ASTNode *node;
}

%start program

%token <id>  TOKEN_IDENTIFIER
%token <num> TOKEN_NUMERAL
%token       TOKEN_ASSIGN
%token       TOKEN_LEFT_PARENTHESIS TOKEN_RIGHT_PARENTHESIS
%token       TOKEN_SEMICOLON
%token       TOKEN_SKIP
%token       TOKEN_IF TOKEN_THEN TOKEN_ELSE TOKEN_END TOKEN_WHILE TOKEN_DO
%token       TOKEN_PLUS TOKEN_MINUS TOKEN_MULTIPLY
%token       TOKEN_NOT TOKEN_OR TOKEN_AND
%token       TOKEN_EQUALS TOKEN_NOT_EQUALS TOKEN_LESS_THAN TOKEN_LESS_EQUAL TOKEN_GREATER_THAN TOKEN_GREATER_EQUAL

%type <node> program statement variable arithmetic_expression boolean_expression
%type <op>   arithmetic_operation boolean_operation relational_operation


%%
  
program               : statement
                        { ast_root = $1; }
                      ;

statement             : TOKEN_SKIP
                        { $$ = ast_skip(); }
                      | variable TOKEN_ASSIGN arithmetic_expression
                        { $$ = ast_assign($1, $3); }
                      | TOKEN_LEFT_PARENTHESIS statement TOKEN_SEMICOLON statement TOKEN_RIGHT_PARENTHESIS
                        { $$ = ast_seq($2, $4); }
                      | TOKEN_IF boolean_expression TOKEN_THEN statement TOKEN_ELSE statement TOKEN_END
                        { $$ = ast_if($2, $4, $6); }
                      | TOKEN_WHILE boolean_expression TOKEN_DO statement TOKEN_END
                        { $$ = ast_while($2, $4); }
                      ;

variable              : TOKEN_IDENTIFIER
                        { $$ = ast_var($1); }
                      ;

arithmetic_expression : TOKEN_LEFT_PARENTHESIS arithmetic_expression arithmetic_operation arithmetic_expression TOKEN_RIGHT_PARENTHESIS
                        { $$ = ast_aop($3, $2, $4); }
                      | variable
                        { $$ = $1; }
                      | TOKEN_NUMERAL
                        { $$ = ast_int($1); }
                      ;

arithmetic_operation  : TOKEN_PLUS
                        { $$ = AOP_ADD; }
                      | TOKEN_MINUS
                        { $$ = AOP_SUB; }
                      | TOKEN_MULTIPLY
                        { $$ = AOP_MUL; }
                      ;

boolean_expression    : TOKEN_LEFT_PARENTHESIS boolean_expression boolean_operation boolean_expression TOKEN_RIGHT_PARENTHESIS
                        { $$ = ast_bop($3, $2, $4); }
                      | TOKEN_NOT boolean_expression
                        { $$ = ast_not($2); }
                      | arithmetic_expression relational_operation arithmetic_expression
                        { $$ = ast_rop($2, $1, $3); }
                      ;

boolean_operation     : TOKEN_OR
                        { $$ = BOP_OR; }
                      | TOKEN_AND
                        { $$ = BOP_AND; }
                      ;

relational_operation  : TOKEN_EQUALS
                        { $$ = ROP_EQ; }
                      | TOKEN_NOT_EQUALS
                        { $$ = ROP_NE; }
                      | TOKEN_LESS_THAN
                        { $$ = ROP_LT; }
                      | TOKEN_LESS_EQUAL
                        { $$ = ROP_LE; }
                      | TOKEN_GREATER_THAN
                        { $$ = ROP_GT; }
                      | TOKEN_GREATER_EQUAL
                        { $$ = ROP_GE; }
                      ;

%%