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   13 use strict;
  3         3  
  3         119  
23 3     3   9 use warnings;
  3         3  
  3         74  
24              
25 3     3   969 use Erlang::Parser::Node::Directive;
  3         8  
  3         97  
26 3     3   1365 use Erlang::Parser::Node::DefList;
  3         38  
  3         75  
27 3     3   1059 use Erlang::Parser::Node::Def;
  3         5  
  3         77  
28 3     3   1121 use Erlang::Parser::Node::WhenList;
  3         6  
  3         73  
29 3     3   1093 use Erlang::Parser::Node::Atom;
  3         6  
  3         75  
30 3     3   986 use Erlang::Parser::Node::Integer;
  3         6  
  3         76  
31 3     3   1046 use Erlang::Parser::Node::BinOp;
  3         5  
  3         76  
32 3     3   1146 use Erlang::Parser::Node::List;
  3         7  
  3         77  
33 3     3   1135 use Erlang::Parser::Node::Variable;
  3         6  
  3         72  
34 3     3   957 use Erlang::Parser::Node::Tuple;
  3         5  
  3         73  
35 3     3   1045 use Erlang::Parser::Node::Macro;
  3         6  
  3         116  
36 3     3   1018 use Erlang::Parser::Node::String;
  3         6  
  3         84  
37 3     3   1031 use Erlang::Parser::Node::Call;
  3         6  
  3         75  
38 3     3   1055 use Erlang::Parser::Node::Alt;
  3         8  
  3         83  
39 3     3   1266 use Erlang::Parser::Node::Try;
  3         9  
  3         96  
40 3     3   1387 use Erlang::Parser::Node::Literal;
  3         6  
  3         74  
41 3     3   1011 use Erlang::Parser::Node::FunRef;
  3         6  
  3         76  
42 3     3   1100 use Erlang::Parser::Node::FunLocal;
  3         8  
  3         77  
43 3     3   1089 use Erlang::Parser::Node::FunLocalCase;
  3         7  
  3         78  
44 3     3   1142 use Erlang::Parser::Node::Case;
  3         6  
  3         83  
45 3     3   1181 use Erlang::Parser::Node::RecordNew;
  3         6  
  3         81  
46 3     3   1102 use Erlang::Parser::Node::VariableRecordAccess;
  3         5  
  3         79  
47 3     3   1115 use Erlang::Parser::Node::VariableRecordUpdate;
  3         7  
  3         74  
48 3     3   1088 use Erlang::Parser::Node::Float;
  3         6  
  3         73  
49 3     3   1910 use Erlang::Parser::Node::BaseInteger;
  3         6  
  3         73  
50 3     3   1105 use Erlang::Parser::Node::BinaryExpr;
  3         6  
  3         82  
51 3     3   1206 use Erlang::Parser::Node::Binary;
  3         6  
  3         75  
52 3     3   1091 use Erlang::Parser::Node::UnOp;
  3         6  
  3         78  
53 3     3   1019 use Erlang::Parser::Node::Begin;
  3         5  
  3         73  
54 3     3   988 use Erlang::Parser::Node::Comprehension;
  3         7  
  3         75  
55 3     3   998 use Erlang::Parser::Node::If;
  3         7  
  3         78  
56 3     3   1076 use Erlang::Parser::Node::IfExpr;
  3         7  
  3         72  
57 3     3   1103 use Erlang::Parser::Node::Receive;
  3         7  
  3         81  
58 3     3   1103 use Erlang::Parser::Node::ReceiveAfter;
  3         7  
  3         24134  
59              
60             sub new_node {
61 82192     82192 1 174574 my ($kind, %args) = @_;
62 82192         2465833 "Erlang::Parser::Node::$kind"->new(%args);
63             }
64             %}
65              
66             %%
67 2     2 1 4  
68 2 50       8 # 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   123 { [] }
73 1852     1852   35915 | root rootstmt { [@{$_[1]}, $_[2]] }
  1852         134084  
74             ;
75              
76             rootstmt:
77 474     474   13389 SUBTRACT ATOM LPAREN exprlist RPAREN PERIOD { new_node 'Directive', directive => $_[2], args => $_[4] }
78 1378     1378   42444 | deflist PERIOD { $_[1] }
79             ;
80              
81             deflist:
82 1378     1378   36424 def { new_node('DefList')->_append($_[1]) }
83 1860     1860   51063 | deflist SEMICOLON def { $_[1]->_append($_[3]) }
84             ;
85              
86             def:
87 3238     3238   83129 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   104461 { new_node 'WhenList' }
92 556     556   16241 | KW_WHEN expr { new_node('WhenList')->_append($_[2]) }
93             # TODO differentiate these. (a;b,c (A)||(B&&C))
94 168     168   6307 | whenlist COMMA expr { $_[1]->_append($_[3]) }
95 42     42   1370 | 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   23035 { [] }
101 17412     17412   302788 | stmtlist { $_[1] }
102             ;
103              
104             stmtlist:
105 22296     22296   1074963 expr { [$_[1]] }
106 17148     17148   807388 | stmtlist COMMA expr { [@{$_[1]}, $_[3]] }
  17148         36396  
107             ;
108              
109             unparenexpr:
110             immexpr
111             | case
112             | fun
113             | binary
114             | receive
115             | comprehension
116             | try
117             | if
118 12     12   334 | KW_BEGIN exprlist KW_END { new_node 'Begin', exprs => $_[2] }
119 6     6   308 | expr SEND expr { new_node 'BinOp', op => '!', a => $_[1], b => $_[3] }
120 84     84   4544 | expr LT expr { new_node 'BinOp', op => '<', a => $_[1], b => $_[3] }
121 166     166   8501 | expr LTE expr { new_node 'BinOp', op => '=<', a => $_[1], b => $_[3] }
122 54     54   2940 | expr GT expr { new_node 'BinOp', op => '>', a => $_[1], b => $_[3] }
123 192     192   10033 | expr GTE expr { new_node 'BinOp', op => '>=', a => $_[1], b => $_[3] }
124 436     436   21272 | expr DIVIDE expr { new_node 'BinOp', op => '/', a => $_[1], b => $_[3] }
125 4     4   229 | expr KW_DIV expr { new_node 'BinOp', op => 'div', a => $_[1], b => $_[3] }
126 46     46   2492 | expr MULTIPLY expr { new_node 'BinOp', op => '*', a => $_[1], b => $_[3] }
127 198     198   11320 | expr ADD expr { new_node 'BinOp', op => '+', a => $_[1], b => $_[3] }
128 124     124   6927 | expr SUBTRACT expr { new_node 'BinOp', op => '-', a => $_[1], b => $_[3] }
129 2894     2894   100283 | expr MATCH expr { new_node 'BinOp', op => '=', a => $_[1], b => $_[3] }
130 254     254   14683 | 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   2439 | expr EQUAL expr { new_node 'BinOp', op => '==', a => $_[1], b => $_[3] }
133 314     314   15696 | expr STRICTLY_EQUAL expr { new_node 'BinOp', op => '=:=', a => $_[1], b => $_[3] }
134 46     46   2359 | 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   1519 | expr KW_BSL expr { new_node 'BinOp', op => 'bsl', a => $_[1], b => $_[3] }
137 10     10   527 | expr KW_BSR expr { new_node 'BinOp', op => 'bsr', a => $_[1], b => $_[3] }
138 30     30   1103 | expr KW_BOR expr { new_node 'BinOp', op => 'bor', a => $_[1], b => $_[3] }
139 52     52   2566 | 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   132 | expr KW_REM expr { new_node 'BinOp', op => 'rem', a => $_[1], b => $_[3] }
143 120     120   4535 | expr KW_ANDALSO expr { new_node 'BinOp', op => 'andalso', a => $_[1], b => $_[3] }
144 238     238   8989 | expr KW_ORELSE expr { new_node 'BinOp', op => 'orelse', a => $_[1], b => $_[3] }
145 6     6   398 | 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   3173 | 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   1120 | KW_NOT expr { new_node 'UnOp', op => 'not', a => $_[2] }
151 20     20   445 | KW_CATCH expr { new_node 'UnOp', op => 'catch', a => $_[2] }
152              
153             # TODO: unhack this.
154 54     54   2731 | 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   279205 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   7809 FLOAT { new_node 'Float', float => $_[1] }
176 380     380   9220 | BASE_INTEGER { new_node 'BaseInteger', baseinteger => $_[1] }
177 3270     3270   79216 | INTEGER { new_node 'Integer', int => $_[1] }
178             | string
179 72     72   1494 | variable OPENRECORD atom { new_node 'VariableRecordAccess', variable => $_[1], record => $_[3] }
180 188     188   4602 | variable newrecord { new_node 'VariableRecordUpdate', variable => $_[1], update => $_[2] }
181 948     948   24014 | 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   326926 ATOM { new_node 'Atom', atom => $_[1] }
192             ;
193              
194             macro:
195 1420     1420   36065 MACRO { new_node 'Macro', macro => substr($_[1], 1) }
196             ;
197              
198             variable:
199 17994     17994   432026 VARIABLE { new_node 'Variable', variable => $_[1] }
200             ;
201              
202             string:
203 6096     6096   156489 STRING { new_node 'String', string => $_[1] }
204 29     29   771 | string STRING { $_[1]->_append($_[2]) }
205             ;
206              
207             call:
208             intcall
209             | extcall
210             ;
211              
212             intcall:
213 6828     6828   179164 parenorimm LPAREN exprlist RPAREN { new_node 'Call', function => $_[1], args => $_[3] }
214             ;
215              
216             extcall:
217 1802     1802   91186 parenorimm COLON intcall { $_[3]->module($_[1]); $_[3] }
  1802         2942  
218             ;
219              
220             list:
221 3360     3360   90641 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   41214 { undef }
227 888     888   55131 | PIPE expr { $_[2] }
228             ;
229              
230             comprehension:
231 52     52   1571 LISTOPEN expr COMPREHENSION exprlist LISTCLOSE { new_node 'Comprehension', output => $_[2], generators => $_[4] }
232 2     2   58 | OPENBINARY binary COMPREHENSION exprlist CLOSEBINARY { new_node 'Comprehension', output => $_[2], generators => $_[4], binary => 1 }
233             ;
234              
235             tuple:
236 4126     4126   106650 TUPLEOPEN exprlist TUPLECLOSE { new_node 'Tuple', elems => $_[2] }
237             ;
238              
239             case:
240 496     496   14998 KW_CASE expr KW_OF altlist KW_END { new_node 'Case', of => $_[2], alts => $_[4] }
241             ;
242              
243             altlist:
244 506     506   12482 alt { [$_[1]] }
245 808     808   20247 | altlist SEMICOLON alt { [@{$_[1]}, $_[3]] }
  808         2041  
246             ;
247              
248             alt:
249 1314     1314   30875 expr whenlist RARROW stmtlist { new_node 'Alt', expr => $_[1], whens => $_[2]->_group, stmts => $_[4] }
250             ;
251              
252             fun:
253             funlocal
254 2     2   65 | 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   966 | KW_FUN ATOM DIVIDE INTEGER { new_node 'FunRef', function => $_[2], arity => $_[4] }
258             ;
259              
260             funlocal:
261 236     236   6733 KW_FUN funlocallist KW_END { new_node 'FunLocal', cases => $_[2] }
262             ;
263            
264             # These are not full nodes.
265             funlocallist:
266 236     236   6178 funlocalcase { [$_[1]] }
267 30     30   777 | funlocallist SEMICOLON funlocalcase { [@{$_[1]}, $_[3]] }
  30         79  
268             ;
269              
270             funlocalcase:
271 266     266   7127 LPAREN exprlist RPAREN whenlist RARROW stmtlist { new_node 'FunLocalCase', args => $_[2], whens => $_[4]->_group, stmts => $_[6] }
272             ;
273              
274             newrecord:
275 448     448   12787 OPENRECORD atom TUPLEOPEN exprlist TUPLECLOSE { new_node 'RecordNew', record => $_[2], exprs => $_[4] }
276             ;
277              
278             binary:
279 1950     1950   81532 OPENBINARY optbinarylist CLOSEBINARY { new_node 'Binary', bexprs => $_[2] }
280             ;
281              
282             # These are not full nodes.
283             optbinarylist:
284 66     66   1251 { [] }
285             | binarylist
286             ;
287              
288             binarylist:
289 1884     1884   43849 binaryexpr { [$_[1]] }
290 1386     1386   31832 | binarylist COMMA binaryexpr { [@{$_[1]}, $_[3]] }
  1386         3305  
291             ;
292              
293             binaryexpr:
294 3270     3270   61067 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   74878 { undef }
300 500     500   14760 | COLON immexpr { $_[2] }
301             ;
302              
303             optbinaryqualifier:
304 2608     2608   42826 { undef }
305 662     662   12206 | DIVIDE binaryqualifier { $_[2] }
306             ;
307              
308             binaryqualifier:
309             ATOM
310 8     8   212 | binaryqualifier SUBTRACT ATOM { "$_[1]-$_[3]" }
311             ;
312              
313             receive:
314 8     8   291 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   39 { undef }
320 6     6   174 | KW_AFTER expr RARROW stmtlist { new_node 'ReceiveAfter', time => $_[2], stmts => $_[4] }
321             ;
322              
323             try:
324 62     62   1932 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   1076 { undef }
330 2     2   41 | KW_OF altlist { $_[2] }
331             ;
332              
333             opttrycatch:
334 10     10   171 { undef }
335 52     52   1094 | KW_CATCH catchaltlist { $_[2] }
336             ;
337              
338             opttryafter:
339 52     52   915 { undef }
340 10     10   179 | KW_AFTER exprlist { $_[2] }
341             ;
342              
343             catchaltlist:
344 52     52   1323 catchalt { [$_[1]] }
345 0     0   0 | catchaltlist SEMICOLON catchalt { [@{$_[1]}, $_[3]] }
  0         0  
346             ;
347              
348             catchalt:
349 44     44   1153 ATOM COLON expr whenlist RARROW stmtlist { new_node 'Alt', catch => 1, class => $_[1], expr => $_[3], whens => $_[4]->_group, stmts => $_[6] }
350 6     6   164 | VARIABLE COLON expr whenlist RARROW stmtlist { new_node 'Alt', catch => 1, class => $_[1], expr => $_[3], whens => $_[4]->_group, stmts => $_[6] }
351 2     2   51 | expr whenlist RARROW stmtlist { new_node 'Alt', catch => 1, expr => $_[1], whens => $_[2]->_group, stmts => $_[4] }
352             ;
353              
354             if:
355 4     4   113 KW_IF iflist KW_END { new_node 'If', cases => $_[2] }
356             ;
357              
358             iflist:
359 4     4   97 ifexpr { [$_[1]] }
360 4     4   97 | iflist SEMICOLON ifexpr { [@{$_[1]}, $_[3]] }
  4         11  
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   355 expr { [$_[1]] }
369 2     2   73 | ifseq COMMA expr { [@{$_[1]}, $_[3]] }
  2         6  
370 2         3298 ;
371             %%
372              
373 2         164 =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: