Mercurial > projects > dang
annotate parser/Parser.d @ 44:495188f9078e new_gen
Big update - Moving towards a better, more seperated parser
The parser no loner creates the AST directly, but through
callbacks(actions). This means the parser can be run with a different set
of actions that do something else.
The parser is not back to full strength yet, the main thing missing is the
various statements and structs.
Also added a SmallArray that uses the stack only until a given size is
exceeded, after which the array is copied unto the heap.
author | Anders Halager <halager@gmail.com> |
---|---|
date | Wed, 23 Apr 2008 00:57:45 +0200 |
parents | 858b9805843d |
children | 9bc660cbdbec |
rev | line source |
---|---|
1 | 1 module parser.Parser; |
2 | |
3 import lexer.Lexer, | |
4 lexer.Token; | |
5 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
6 import parser.Action; |
1 | 7 |
21
0fb2d13dce37
Now working with gdc also (gdc use reverse paremeter validating on function calls)
johnsen@johnsen-laptop
parents:
12
diff
changeset
|
8 import misc.Error; |
0fb2d13dce37
Now working with gdc also (gdc use reverse paremeter validating on function calls)
johnsen@johnsen-laptop
parents:
12
diff
changeset
|
9 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
10 import basic.SmallArray; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
11 |
1 | 12 import tango.io.Stdout, |
13 Integer = tango.text.convert.Integer; | |
14 | |
15 class Parser | |
16 { | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
17 Action action; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
18 alias Object Exp; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
19 alias Object Stmt; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
20 alias Object Decl; |
1 | 21 |
22 public: | |
23 Decl[] parse(Lexer lexer) | |
24 { | |
25 this.lexer = lexer; | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
26 action = new AstAction; |
1 | 27 |
28 | |
29 Decl[] declarations; | |
30 | |
31 while(lexer.peek.type != Tok.EOF) | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
32 declarations ~= parseRootDecl(); |
1 | 33 |
34 return declarations; | |
35 } | |
36 | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
37 Decl parseRootDecl() |
1 | 38 { |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
39 Token t = lexer.peek; |
1 | 40 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
41 if (t.isBasicType || t.isIdentifier) |
1 | 42 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
43 Id type = Id(lexer.next); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
44 Id iden = Id(require(Tok.Identifier)); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
45 Token next = lexer.peek(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
46 if (next.type == Tok.Seperator) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
47 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
48 Token sep = lexer.next(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
49 return action.actOnDeclarator(type, iden, null); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
50 } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
51 else if (next.type == Tok.Assign) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
52 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
53 Token assign = lexer.next(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
54 Exp exp = parseExpression(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
55 require(Tok.Seperator); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
56 return action.actOnDeclarator(type, iden, exp); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
57 } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
58 else if (next.type == Tok.OpenParentheses) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
59 return parseFunc(type, iden); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
60 else |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
61 throw error(__LINE__, PE.UnexpectedTok) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
62 .tok(next) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
63 .arg(next.getType); |
1 | 64 } |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
65 else if (t.type == Tok.Struct) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
66 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
67 } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
68 char[] c = t.getType; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
69 throw error(__LINE__, PE.UnexpectedTok).tok(t).arg(c); |
1 | 70 } |
71 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
72 /** |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
73 Parse statements. |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
74 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
75 This is the place to attack! |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
76 */ |
1 | 77 Stmt parseStatement() |
78 { | |
79 Token t = lexer.peek; | |
80 | |
81 switch(t.type) | |
82 { | |
83 case Tok.Return: | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
84 Token ret = lexer.next; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
85 Exp exp = parseExpression(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
86 require(Tok.Seperator); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
87 return action.actOnReturnStmt(ret, exp); |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
88 |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
89 case Tok.If: |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
90 return null; |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
91 |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
92 case Tok.While: |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
93 return null; |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
94 |
1 | 95 case Tok.Identifier: |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
96 return null; |
1 | 97 |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
98 case Tok.Switch: |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
99 return null; |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
100 |
1 | 101 default: |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
102 return null; |
1 | 103 } |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
104 error(__LINE__, "").tok(t); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
105 return null; |
1 | 106 } |
107 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
108 /** |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
109 Parses a function/method given the already parsed |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
110 */ |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
111 Decl parseFunc(ref Id type, ref Id name) |
1 | 112 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
113 Decl func = action.actOnStartOfFunctionDef(type, name); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
114 parseFuncArgs(func); |
1 | 115 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
116 Stmt stmt = parseCompoundStatement(); |
1 | 117 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
118 action.actOnEndOfFunction(func, stmt); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
119 return func; |
1 | 120 } |
121 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
122 /** |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
123 Parse the function arguments, assumes current token is (. |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
124 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
125 Both the intitial paren and the ending paren is consumed. |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
126 */ |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
127 void parseFuncArgs(Decl func) |
1 | 128 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
129 require(Tok.OpenParentheses); // Remove the "(" token. |
1 | 130 |
131 while(lexer.peek.type != Tok.CloseParentheses) | |
132 { | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
133 auto t = parseType(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
134 auto i = parseIdentifier(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
135 action.addFuncArg(func, t, i); |
1 | 136 |
137 if(lexer.peek.type == Tok.Comma) | |
138 lexer.next; | |
139 } | |
140 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
141 require(Tok.CloseParentheses); // Remove the ")" |
1 | 142 } |
143 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
144 /** |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
145 Parses a function-body or similar, expects { to be current token. |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
146 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
147 Will consume both the starting { and ending } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
148 */ |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
149 Stmt parseCompoundStatement() |
1 | 150 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
151 Token lbrace = require(Tok.OpenBrace); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
152 SmallArray!(Stmt, 32) stmts; // Try to use the stack only |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
153 while (lexer.peek.type != Tok.CloseBrace) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
154 stmts ~= parseStatement(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
155 Token rbrace = require(Tok.CloseBrace); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
156 return action.actOnCompoundStmt(lbrace, rbrace, stmts.unsafe()); |
1 | 157 } |
158 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
159 Id parseIdentifier() |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
160 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
161 Token tok = lexer.next; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
162 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
163 if (tok.type is Tok.Identifier) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
164 return Id(tok); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
165 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
166 throw error(__LINE__, PE.UnexpectedTokSingle) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
167 .arg(tok.getType) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
168 .arg(Tok.Identifier) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
169 .tok(tok); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
170 } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
171 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
172 Id parseType() |
1 | 173 { |
174 Token type = lexer.next; | |
175 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
176 if (type.isBasicType || type.type == Tok.Identifier) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
177 return Id(type); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
178 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
179 char[] c = type.getType; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
180 error(__LINE__, "Unexpected token in Type parsing. Got %0").arg(c); |
1 | 181 } |
182 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
183 private: |
1 | 184 // -- Expression parsing -- // |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
185 Exp parseExpIdentifier(Exp target) |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
186 { |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
187 switch(lexer.peek.type) |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
188 { |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
189 case Tok.Dot: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
190 switch(lexer.peek(1).type) |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
191 { |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
192 case Tok.Identifier: |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
193 Token op = lexer.next; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
194 Id member = Id(lexer.next); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
195 Exp exp = action.actOnMemberReference(target, op.location, member); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
196 return parseExpIdentifier(exp); |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
197 default: |
30
3147a52d1247
Ooops.. should have compiled before commit.. now works again
Anders Halager <halager@gmail.com>
parents:
29
diff
changeset
|
198 Token t = lexer.peek(1); |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
199 throw error(__LINE__, "Expected identifier after '.'").tok(t); |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
200 } |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
201 default: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
202 return target; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
203 } |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
204 } |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
205 |
1 | 206 Exp parseExpression(int p = 0) |
207 { | |
208 auto exp = P(); | |
209 Token next = lexer.peek(); | |
210 BinOp* op = null; | |
211 while ((op = binary(next.type)) != null && op.prec >= p) | |
212 { | |
213 lexer.next(); | |
214 int q = op.leftAssoc? 1 + op.prec : op.prec; | |
215 auto exp2 = parseExpression(q); | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
216 exp = action.actOnBinaryOp(op.operator, exp, exp2); |
1 | 217 next = lexer.peek(); |
218 } | |
219 | |
220 return exp; | |
221 } | |
222 | |
223 Exp P() | |
224 { | |
225 Token next = lexer.next(); | |
226 if (auto op = unary(next.type)) | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
227 return action.actOnUnaryOp(next, parseExpression(op.prec)); |
1 | 228 else if (next.type == Tok.OpenParentheses) |
229 { | |
230 auto e = parseExpression(0); | |
231 require(Tok.CloseParentheses); | |
232 return e; | |
233 } | |
234 else if (next.type == Tok.Identifier) | |
235 { | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
236 Exp value = action.actOnIdentifierExp(Id(next)); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
237 Exp iden = parseExpIdentifier(value); |
1 | 238 switch(lexer.peek.type) |
239 { | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
240 // TODO: Function calls are parsed but ignored |
1 | 241 case Tok.OpenParentheses: |
242 lexer.next; | |
243 Exp[] args; | |
244 while(lexer.peek.type != Tok.CloseParentheses) | |
245 { | |
246 if(lexer.peek.type == Tok.Comma) | |
247 { | |
248 lexer.next; | |
249 } | |
250 args ~= parseExpression(); | |
251 } | |
252 | |
253 lexer.next(); | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
254 return null;//new CallExp(iden, args); |
1 | 255 |
256 default: | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
257 return iden; |
1 | 258 } |
259 } | |
260 else if (next.type == Tok.Integer) | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
261 return action.actOnNumericConstant(next); |
1 | 262 |
263 Stdout.formatln("{}", next.getType); | |
264 assert(0, "Should not happen"); | |
265 } | |
266 | |
267 struct UnOp | |
268 { | |
269 Tok tokenType; | |
270 int prec; | |
271 } | |
272 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
273 static const UnOp[] _unary = [{Tok.Sub, 4}]; |
1 | 274 UnOp* unary(Tok t) |
275 { | |
276 foreach (ref op; _unary) | |
277 if (op.tokenType == t) | |
278 return &op; | |
279 return null; | |
280 } | |
281 | |
282 struct BinOp | |
283 { | |
284 Tok tokenType; | |
285 int prec; | |
286 bool leftAssoc; | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
287 Operator operator; |
1 | 288 } |
289 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
290 static const BinOp[] _binary = |
1 | 291 [ |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
292 {Tok.Eq, 2, true, Operator.Eq}, |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
293 {Tok.Ne, 2, true, Operator.Ne}, |
10
2f493057cf17
Some support for the rest of the boolean operators
Anders Halager <halager@gmail.com>
parents:
7
diff
changeset
|
294 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
295 {Tok.Lt, 2, true, Operator.Lt}, |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
296 {Tok.Le, 2, true, Operator.Le}, |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
297 {Tok.Gt, 2, true, Operator.Gt}, |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
298 {Tok.Ge, 2, true, Operator.Ge}, |
10
2f493057cf17
Some support for the rest of the boolean operators
Anders Halager <halager@gmail.com>
parents:
7
diff
changeset
|
299 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
300 {Tok.Add, 3, true, Operator.Add}, |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
301 {Tok.Sub, 3, true, Operator.Sub}, |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
302 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
303 {Tok.Mul, 5, true, Operator.Mul}, |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
304 {Tok.Div, 5, true, Operator.Div} |
1 | 305 ]; |
306 BinOp* binary(Tok t) | |
307 { | |
308 foreach (ref op; _binary) | |
309 if (op.tokenType == t) | |
310 return &op; | |
311 return null; | |
312 } | |
313 | |
314 private: | |
315 | |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
316 Token require(Tok t) |
1 | 317 { |
318 if (lexer.peek().type != t) | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
319 throw error(__LINE__, PE.UnexpectedTokSingle) |
29
41d23f2762c3
Merge, and updated Error class
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
320 .arg(lexer.peek.getType) |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
321 .arg(t); |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
322 return lexer.next(); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
323 } |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
324 |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
325 bool skip(Tok t) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
326 { |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
327 if (lexer.peek().type != t) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
328 return false; |
1 | 329 lexer.next(); |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
330 return true; |
1 | 331 } |
332 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
333 Error error(uint line, char[] errMsg) |
1 | 334 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
335 Location loc = lexer.peek.location; |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
336 auto e = |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
337 new Error("Parser.d(" ~ Integer.toString(line) ~ "): " ~errMsg); |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
338 e.loc(loc); |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
339 return e; |
1 | 340 } |
341 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
342 struct PE |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
343 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
344 static char[] |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
345 UnexpectedTokMulti = "Unexpected token, got %0 expected one of %1", |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
346 UnexpectedTokSingle = "Unexpected token, got %0 expected %1", |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
347 UnexpectedTok = "Unexpected token %0"; |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
348 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
349 static char[] |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
350 CaseValueMustBeInt = "Cases can only be integer literals"; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
351 } |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
352 |
1 | 353 Lexer lexer; |
354 } |