File Coverage

lib/Erlang/Parser/Parser.yp
Criterion Covered Total %
statement 226 238 94.9
branch 1 2 50.0
condition n/a
subroutine 142 153 92.8
pod 2 2 100.0
total 371 395 93.9


line stmt bran cond sub pod time code
1             # Copyright 2011-2012 Yuki Izumi. ( anneli AT cpan DOT org )
2             # This is free software; you can redistribute it and/or modify it under the
3             # same terms as Perl itself.
4              
5             %nonassoc KW_CATCH
6              
7             # ???
8             %nonassoc LARROW LDARROW
9              
10             %right MATCH SEND
11             %left KW_ORELSE
12             %left KW_ANDALSO
13             %nonassoc EQUAL NOT_EQUAL LTE GTE LT GT STRICTLY_EQUAL STRICTLY_NOT_EQUAL
14             %right LISTADD LISTSUBTRACT
15             %left ADD SUBTRACT KW_BOR KW_BXOR KW_BSL KW_BSR KW_OR KW_XOR
16             %left DIVIDE MULTIPLY KW_DIV KW_REM KW_AND KW_BAND
17             %left NEG POS KW_BNOT KW_NOT
18             %nonassoc OPENRECORD
19             %nonassoc COLON
20              
21             %{
22 3     3   15 use strict;
  3         3  
  3         79  
23 3     3   11 use warnings;
  3         4  
  3         87  
24              
25 3     3   1073 use Erlang::Parser::Node::Directive;
  3         7  
  3         124  
26 3     3   1440 use Erlang::Parser::Node::DefList;
  3         37  
  3         82  
27 3     3   1219 use Erlang::Parser::Node::Def;
  3         9  
  3         93  
28 3     3   1296 use Erlang::Parser::Node::WhenList;
  3         6  
  3         93  
29 3     3   1238 use Erlang::Parser::Node::Atom;
  3         7  
  3         90  
30 3     3   1210 use Erlang::Parser::Node::Integer;
  3         8  
  3         90  
31 3     3   1118 use Erlang::Parser::Node::BinOp;
  3         7  
  3         89  
32 3     3   1199 use Erlang::Parser::Node::List;
  3         7  
  3         83  
33 3     3   1234 use Erlang::Parser::Node::Variable;
  3         6  
  3         79  
34 3     3   1183 use Erlang::Parser::Node::Tuple;
  3         6  
  3         87  
35 3     3   1150 use Erlang::Parser::Node::Macro;
  3         7  
  3         87  
36 3     3   1181 use Erlang::Parser::Node::String;
  3         6  
  3         82  
37 3     3   1123 use Erlang::Parser::Node::Call;
  3         8  
  3         103  
38 3     3   1513 use Erlang::Parser::Node::Alt;
  3         8  
  3         169  
39 3     3   1343 use Erlang::Parser::Node::Try;
  3         8  
  3         97  
40 3     3   1556 use Erlang::Parser::Node::Literal;
  3         7  
  3         88  
41 3     3   1304 use Erlang::Parser::Node::FunRef;
  3         7  
  3         90  
42 3     3   1699 use Erlang::Parser::Node::FunLocal;
  3         8  
  3         88  
43 3     3   1238 use Erlang::Parser::Node::FunLocalCase;
  3         8  
  3         92  
44 3     3   1377 use Erlang::Parser::Node::Case;
  3         8  
  3         97  
45 3     3   1459 use Erlang::Parser::Node::RecordNew;
  3         7  
  3         83  
46 3     3   1112 use Erlang::Parser::Node::VariableRecordAccess;
  3         5  
  3         84  
47 3     3   1151 use Erlang::Parser::Node::VariableRecordUpdate;
  3         7  
  3         102  
48 3     3   1360 use Erlang::Parser::Node::Float;
  3         6  
  3         85  
49 3     3   2065 use Erlang::Parser::Node::BaseInteger;
  3         8  
  3         82  
50 3     3   1194 use Erlang::Parser::Node::BinaryExpr;
  3         8  
  3         86  
51 3     3   1187 use Erlang::Parser::Node::Binary;
  3         7  
  3         81  
52 3     3   1312 use Erlang::Parser::Node::UnOp;
  3         6  
  3         87  
53 3     3   1108 use Erlang::Parser::Node::Begin;
  3         6  
  3         81  
54 3     3   1153 use Erlang::Parser::Node::Comprehension;
  3         7  
  3         94  
55 3     3   1180 use Erlang::Parser::Node::If;
  3         6  
  3         85  
56 3     3   1212 use Erlang::Parser::Node::IfExpr;
  3         7  
  3         87  
57 3     3   1305 use Erlang::Parser::Node::Receive;
  3         9  
  3         95  
58 3     3   1413 use Erlang::Parser::Node::ReceiveAfter;
  3         7  
  3         24987  
59              
60             sub new_node {
61 82192     82192 1 172081 my ($kind, %args) = @_;
62 82192         2423280 "Erlang::Parser::Node::$kind"->new(%args);
63             }
64             %}
65              
66             %%
67 2     2 1 4  
68 2 50       7 # TODO: A few of these lists are flawed in that their optional type isn't done correctly
69             # (they allow constructs like [, 1, 2]). Fix this.
70              
71             root:
72 2     2   143 { [] }
73 1852     1852   34770 | root rootstmt { [@{$_[1]}, $_[2]] }
  1852         129490  
74             ;
75              
76             rootstmt:
77 474     474   13325 SUBTRACT ATOM LPAREN exprlist RPAREN PERIOD { new_node 'Directive', directive => $_[2], args => $_[4] }
78 1378     1378   40864 | deflist PERIOD { $_[1] }
79             ;
80              
81             deflist:
82 1378     1378   34817 def { new_node('DefList')->_append($_[1]) }
83 1860     1860   50068 | deflist SEMICOLON def { $_[1]->_append($_[3]) }
84             ;
85              
86             def:
87 3238     3238   80096 ATOM LPAREN exprlist RPAREN whenlist RARROW stmtlist { new_node 'Def', def => $_[1], args => $_[3], whens => $_[5]->_group, stmts => $_[7] }
88             ;
89              
90             whenlist:
91 4314     4314   102603 { new_node 'WhenList' }
92 556     556   16111 | KW_WHEN expr { new_node('WhenList')->_append($_[2]) }
93             # TODO differentiate these. (a;b,c (A)||(B&&C))
94 168     168   6332 | whenlist COMMA expr { $_[1]->_append($_[3]) }
95 42     42   1356 | whenlist SEMICOLON expr { $_[1]->_group->_append($_[3]) }
96             ;
97              
98             # somehow this is an idiom. exprlist = 0 or more. stmtlist = 1 or more.
99             exprlist:
100 1466     1466   23503 { [] }
101 17412     17412   294108 | stmtlist { $_[1] }
102             ;
103              
104             stmtlist:
105 22296     22296   1047377 expr { [$_[1]] }
106 17148     17148   784745 | stmtlist COMMA expr { [@{$_[1]}, $_[3]] }
  17148         37283  
107             ;
108              
109             unparenexpr:
110             immexpr
111             | case
112             | fun
113             | binary
114             | receive
115             | comprehension
116             | try
117             | if
118 12     12   332 | KW_BEGIN exprlist KW_END { new_node 'Begin', exprs => $_[2] }
119 6     6   298 | expr SEND expr { new_node 'BinOp', op => '!', a => $_[1], b => $_[3] }
120 84     84   4427 | expr LT expr { new_node 'BinOp', op => '<', a => $_[1], b => $_[3] }
121 166     166   8374 | expr LTE expr { new_node 'BinOp', op => '=<', a => $_[1], b => $_[3] }
122 54     54   2804 | expr GT expr { new_node 'BinOp', op => '>', a => $_[1], b => $_[3] }
123 192     192   9642 | expr GTE expr { new_node 'BinOp', op => '>=', a => $_[1], b => $_[3] }
124 436     436   20332 | expr DIVIDE expr { new_node 'BinOp', op => '/', a => $_[1], b => $_[3] }
125 4     4   225 | expr KW_DIV expr { new_node 'BinOp', op => 'div', a => $_[1], b => $_[3] }
126 46     46   2410 | expr MULTIPLY expr { new_node 'BinOp', op => '*', a => $_[1], b => $_[3] }
127 198     198   11031 | expr ADD expr { new_node 'BinOp', op => '+', a => $_[1], b => $_[3] }
128 124     124   6662 | expr SUBTRACT expr { new_node 'BinOp', op => '-', a => $_[1], b => $_[3] }
129 2894     2894   96625 | expr MATCH expr { new_node 'BinOp', op => '=', a => $_[1], b => $_[3] }
130 254     254   14645 | expr LISTADD expr { new_node 'BinOp', op => '++', a => $_[1], b => $_[3] }
131 0     0   0 | expr LISTSUBTRACT expr { new_node 'BinOp', op => '--', a => $_[1], b => $_[3] }
132 46     46   2378 | expr EQUAL expr { new_node 'BinOp', op => '==', a => $_[1], b => $_[3] }
133 314     314   15108 | expr STRICTLY_EQUAL expr { new_node 'BinOp', op => '=:=', a => $_[1], b => $_[3] }
134 46     46   2315 | expr STRICTLY_NOT_EQUAL expr { new_node 'BinOp', op => '=/=', a => $_[1], b => $_[3] }
135 0     0   0 | expr NOT_EQUAL expr { new_node 'BinOp', op => '/=', a => $_[1], b => $_[3] }
136 30     30   1494 | expr KW_BSL expr { new_node 'BinOp', op => 'bsl', a => $_[1], b => $_[3] }
137 10     10   823 | expr KW_BSR expr { new_node 'BinOp', op => 'bsr', a => $_[1], b => $_[3] }
138 30     30   1098 | expr KW_BOR expr { new_node 'BinOp', op => 'bor', a => $_[1], b => $_[3] }
139 52     52   2429 | expr KW_BAND expr { new_node 'BinOp', op => 'band', a => $_[1], b => $_[3] }
140 0     0   0 | expr KW_BXOR expr { new_node 'BinOp', op => 'bxor', a => $_[1], b => $_[3] }
141 0     0   0 | expr KW_XOR expr { new_node 'BinOp', op => 'xor', a => $_[1], b => $_[3] }
142 2     2   127 | expr KW_REM expr { new_node 'BinOp', op => 'rem', a => $_[1], b => $_[3] }
143 120     120   4385 | expr KW_ANDALSO expr { new_node 'BinOp', op => 'andalso', a => $_[1], b => $_[3] }
144 238     238   8927 | expr KW_ORELSE expr { new_node 'BinOp', op => 'orelse', a => $_[1], b => $_[3] }
145 6     6   390 | expr KW_AND expr { new_node 'BinOp', op => 'and', a => $_[1], b => $_[3] }
146 0     0   0 | expr KW_OR expr { new_node 'BinOp', op => 'or', a => $_[1], b => $_[3] }
147 66     66   3137 | SUBTRACT expr %prec NEG { new_node 'UnOp', op => '-', a => $_[2] }
148 0     0   0 | ADD expr %prec POS { new_node 'UnOp', op => '+', a => $_[2] }
149 0     0   0 | KW_BNOT expr { new_node 'UnOp', op => 'bnot', a => $_[2] }
150 18     18   1062 | KW_NOT expr { new_node 'UnOp', op => 'not', a => $_[2] }
151 20     20   420 | KW_CATCH expr { new_node 'UnOp', op => 'catch', a => $_[2] }
152              
153             # TODO: unhack this.
154 54     54   2674 | expr LARROW expr { new_node 'BinOp', op => '<-', a => $_[1], b => $_[3] }
155 0     0   0 | expr LDARROW expr { new_node 'BinOp', op => '<=', a => $_[1], b => $_[3] }
156              
157             | call
158             ;
159              
160             parenexpr:
161 5105     5105   267136 LPAREN expr RPAREN { $_[2] }
162             ;
163              
164             expr:
165             unparenexpr
166             | parenexpr
167             ;
168              
169             parenorimm:
170             parenexpr
171             | immexpr
172             ;
173              
174             immexpr:
175 304     304   7491 FLOAT { new_node 'Float', float => $_[1] }
176 380     380   8924 | BASE_INTEGER { new_node 'BaseInteger', baseinteger => $_[1] }
177 3270     3270   78461 | INTEGER { new_node 'Integer', int => $_[1] }
178             | string
179 72     72   1404 | variable OPENRECORD atom { new_node 'VariableRecordAccess', variable => $_[1], record => $_[3] }
180 188     188   4600 | variable newrecord { new_node 'VariableRecordUpdate', variable => $_[1], update => $_[2] }
181 948     948   23873 | LITERAL { new_node 'Literal', literal => substr($_[1], 1) }
182             | list
183             | tuple
184             | newrecord
185             | macro
186             | variable
187             | atom
188             ;
189              
190             atom:
191 13512     13512   320681 ATOM { new_node 'Atom', atom => $_[1] }
192             ;
193              
194             macro:
195 1420     1420   35694 MACRO { new_node 'Macro', macro => substr($_[1], 1) }
196             ;
197              
198             variable:
199 17994     17994   424089 VARIABLE { new_node 'Variable', variable => $_[1] }
200             ;
201              
202             string:
203 6096     6096   151782 STRING { new_node 'String', string => $_[1] }
204 29     29   765 | string STRING { $_[1]->_append($_[2]) }
205             ;
206              
207             call:
208             intcall
209             | extcall
210             ;
211              
212             intcall:
213 6828     6828   174778 parenorimm LPAREN exprlist RPAREN { new_node 'Call', function => $_[1], args => $_[3] }
214             ;
215              
216             extcall:
217 1802     1802   88043 parenorimm COLON intcall { $_[3]->module($_[1]); $_[3] }
  1802         3291  
218             ;
219              
220             list:
221 3360     3360   89640 LISTOPEN exprlist listcdr LISTCLOSE { new_node 'List', elems => $_[2], cdr => $_[3] }
222             ;
223              
224             # This is not a full node.
225             listcdr:
226 2472     2472   41897 { undef }
227 888     888   54054 | PIPE expr { $_[2] }
228             ;
229              
230             comprehension:
231 52     52   1502 LISTOPEN expr COMPREHENSION exprlist LISTCLOSE { new_node 'Comprehension', output => $_[2], generators => $_[4] }
232 2     2   56 | OPENBINARY binary COMPREHENSION exprlist CLOSEBINARY { new_node 'Comprehension', output => $_[2], generators => $_[4], binary => 1 }
233             ;
234              
235             tuple:
236 4126     4126   104343 TUPLEOPEN exprlist TUPLECLOSE { new_node 'Tuple', elems => $_[2] }
237             ;
238              
239             case:
240 496     496   14598 KW_CASE expr KW_OF altlist KW_END { new_node 'Case', of => $_[2], alts => $_[4] }
241             ;
242              
243             altlist:
244 506     506   12204 alt { [$_[1]] }
245 808     808   19597 | altlist SEMICOLON alt { [@{$_[1]}, $_[3]] }
  808         2122  
246             ;
247              
248             alt:
249 1314     1314   29975 expr whenlist RARROW stmtlist { new_node 'Alt', expr => $_[1], whens => $_[2]->_group, stmts => $_[4] }
250             ;
251              
252             fun:
253             funlocal
254 2     2   64 | KW_FUN atom COLON ATOM DIVIDE INTEGER { new_node 'FunRef', module => $_[2], function => $_[4], arity => $_[6] }
255 0     0   0 | KW_FUN macro COLON ATOM DIVIDE INTEGER { new_node 'FunRef', module => $_[2], function => $_[4], arity => $_[6] }
256 0     0   0 | KW_FUN variable COLON ATOM DIVIDE INTEGER { new_node 'FunRef', module => $_[2], function => $_[4], arity => $_[6] }
257 36     36   948 | KW_FUN ATOM DIVIDE INTEGER { new_node 'FunRef', function => $_[2], arity => $_[4] }
258             ;
259              
260             funlocal:
261 236     236   6563 KW_FUN funlocallist KW_END { new_node 'FunLocal', cases => $_[2] }
262             ;
263            
264             # These are not full nodes.
265             funlocallist:
266 236     236   5921 funlocalcase { [$_[1]] }
267 30     30   789 | funlocallist SEMICOLON funlocalcase { [@{$_[1]}, $_[3]] }
  30         82  
268             ;
269              
270             funlocalcase:
271 266     266   6859 LPAREN exprlist RPAREN whenlist RARROW stmtlist { new_node 'FunLocalCase', args => $_[2], whens => $_[4]->_group, stmts => $_[6] }
272             ;
273              
274             newrecord:
275 448     448   12709 OPENRECORD atom TUPLEOPEN exprlist TUPLECLOSE { new_node 'RecordNew', record => $_[2], exprs => $_[4] }
276             ;
277              
278             binary:
279 1950     1950   80008 OPENBINARY optbinarylist CLOSEBINARY { new_node 'Binary', bexprs => $_[2] }
280             ;
281              
282             # These are not full nodes.
283             optbinarylist:
284 66     66   1141 { [] }
285             | binarylist
286             ;
287              
288             binarylist:
289 1884     1884   43535 binaryexpr { [$_[1]] }
290 1386     1386   31208 | binarylist COMMA binaryexpr { [@{$_[1]}, $_[3]] }
  1386         3391  
291             ;
292              
293             binaryexpr:
294 3270     3270   59525 parenorimm optbinarysize optbinaryqualifier { new_node 'BinaryExpr', output => $_[1], size => $_[2], qualifier => $_[3] }
295             ;
296              
297             # These are not full nodes.
298             optbinarysize:
299 2770     2770   75721 { undef }
300 500     500   14497 | COLON immexpr { $_[2] }
301             ;
302              
303             optbinaryqualifier:
304 2608     2608   42929 { undef }
305 662     662   12085 | DIVIDE binaryqualifier { $_[2] }
306             ;
307              
308             binaryqualifier:
309             ATOM
310 8     8   207 | binaryqualifier SUBTRACT ATOM { "$_[1]-$_[3]" }
311             ;
312              
313             receive:
314 8     8   307 KW_RECEIVE altlist after KW_END { new_node 'Receive', alts => $_[2], aft => $_[3] }
315             ;
316              
317             # This is not a full node.
318             after:
319 2     2   38 { undef }
320 6     6   148 | KW_AFTER expr RARROW stmtlist { new_node 'ReceiveAfter', time => $_[2], stmts => $_[4] }
321             ;
322              
323             try:
324 62     62   1797 KW_TRY exprlist opttryof opttrycatch opttryafter KW_END { new_node 'Try', exprs => $_[2], of => $_[3], catch => $_[4], aft => $_[5] }
325             ;
326              
327             # These are not full nodes.
328             opttryof:
329 60     60   1020 { undef }
330 2     2   42 | KW_OF altlist { $_[2] }
331             ;
332              
333             opttrycatch:
334 10     10   184 { undef }
335 52     52   1026 | KW_CATCH catchaltlist { $_[2] }
336             ;
337              
338             opttryafter:
339 52     52   923 { undef }
340 10     10   175 | KW_AFTER exprlist { $_[2] }
341             ;
342              
343             catchaltlist:
344 52     52   1324 catchalt { [$_[1]] }
345 0     0   0 | catchaltlist SEMICOLON catchalt { [@{$_[1]}, $_[3]] }
  0         0  
346             ;
347              
348             catchalt:
349 44     44   1104 ATOM COLON expr whenlist RARROW stmtlist { new_node 'Alt', catch => 1, class => $_[1], expr => $_[3], whens => $_[4]->_group, stmts => $_[6] }
350 6     6   158 | VARIABLE COLON expr whenlist RARROW stmtlist { new_node 'Alt', catch => 1, class => $_[1], expr => $_[3], whens => $_[4]->_group, stmts => $_[6] }
351 2     2   50 | expr whenlist RARROW stmtlist { new_node 'Alt', catch => 1, expr => $_[1], whens => $_[2]->_group, stmts => $_[4] }
352             ;
353              
354             if:
355 4     4   112 KW_IF iflist KW_END { new_node 'If', cases => $_[2] }
356             ;
357              
358             iflist:
359 4     4   94 ifexpr { [$_[1]] }
360 4     4   98 | iflist SEMICOLON ifexpr { [@{$_[1]}, $_[3]] }
  4         9  
361             ;
362              
363             ifexpr:
364 8     8   175 ifseq RARROW stmtlist { new_node 'IfExpr', seq => $_[1], stmts => $_[3] }
365             ;
366              
367             ifseq:
368 8     8   336 expr { [$_[1]] }
369 2     2   74 | ifseq COMMA expr { [@{$_[1]}, $_[3]] }
  2         6  
370 2         3292 ;
371             %%
372              
373 2         169 =over 4
374              
375             =item C<new>
376              
377             Creates a new parser object. See L<Parse::Yapp> for more information.
378              
379             =item C<new_node>
380              
381             Helper function used to create new nodes.
382              
383             # These are identical.
384             my $n1 = new_node('X', @y);
385             my $n2 = Erlang::Parser::Node::X->new(@y);
386              
387             =cut
388              
389             1;
390              
391             # vim: set sw=4 ts=4 et filetype=perl: