1TAP::Parser::Grammar(3pmP)erl Programmers Reference GuidTeAP::Parser::Grammar(3pm)
2
3
4

NAME

6       TAP::Parser::Grammar - A grammar for the Test Anything Protocol.
7

VERSION

9       Version 3.17
10

SYNOPSIS

12         use TAP::Parser::Grammar;
13         my $grammar = $self->make_grammar({
14           stream  => $tap_parser_stream,
15           parser  => $tap_parser,
16           version => 12,
17         });
18
19         my $result = $grammar->tokenize;
20

DESCRIPTION

22       "TAP::Parser::Grammar" tokenizes lines from a TAP stream and constructs
23       TAP::Parser::Result subclasses to represent the tokens.
24
25       Do not attempt to use this class directly.  It won't make sense.  It's
26       mainly here to ensure that we will be able to have pluggable grammars
27       when TAP is expanded at some future date (plus, this stuff was really
28       cluttering the parser).
29

METHODS

31   Class Methods
32       "new"
33
34         my $grammar = TAP::Parser::Grammar->new({
35             stream  => $stream,
36             parser  => $parser,
37             version => $version,
38         });
39
40       Returns TAP::Parser grammar object that will parse the specified
41       stream.  Both "stream" and "parser" are required arguments.  If
42       "version" is not set it defaults to 12 (see "set_version" for more
43       details).
44
45   Instance Methods
46       "set_version"
47
48         $grammar->set_version(13);
49
50       Tell the grammar which TAP syntax version to support. The lowest
51       supported version is 12. Although 'TAP version' isn't valid version 12
52       syntax it is accepted so that higher version numbers may be parsed.
53
54       "tokenize"
55
56         my $token = $grammar->tokenize;
57
58       This method will return a TAP::Parser::Result object representing the
59       current line of TAP.
60
61       "token_types"
62
63         my @types = $grammar->token_types;
64
65       Returns the different types of tokens which this grammar can parse.
66
67       "syntax_for"
68
69         my $syntax = $grammar->syntax_for($token_type);
70
71       Returns a pre-compiled regular expression which will match a chunk of
72       TAP corresponding to the token type.  For example (not that you should
73       really pay attention to this, "$grammar->syntax_for('comment')" will
74       return "qr/^#(.*)/".
75
76       "handler_for"
77
78         my $handler = $grammar->handler_for($token_type);
79
80       Returns a code reference which, when passed an appropriate line of TAP,
81       returns the lexed token corresponding to that line.  As a result, the
82       basic TAP parsing loop looks similar to the following:
83
84        my @tokens;
85        my $grammar = TAP::Grammar->new;
86        LINE: while ( defined( my $line = $parser->_next_chunk_of_tap ) ) {
87            foreach my $type ( $grammar->token_types ) {
88                my $syntax  = $grammar->syntax_for($type);
89                if ( $line =~ $syntax ) {
90                    my $handler = $grammar->handler_for($type);
91                    push @tokens => $grammar->$handler($line);
92                    next LINE;
93                }
94            }
95            push @tokens => $grammar->_make_unknown_token($line);
96        }
97

TAP GRAMMAR

99       NOTE:  This grammar is slightly out of date.  There's still some
100       discussion about it and a new one will be provided when we have things
101       better defined.
102
103       The TAP::Parser does not use a formal grammar because TAP is
104       essentially a stream-based protocol.  In fact, it's quite legal to have
105       an infinite stream.  For the same reason that we don't apply regexes to
106       streams, we're not using a formal grammar here.  Instead, we parse the
107       TAP in lines.
108
109       For purposes for forward compatability, any result which does not match
110       the following grammar is currently referred to as
111       TAP::Parser::Result::Unknown.  It is not a parse error.
112
113       A formal grammar would look similar to the following:
114
115        (*
116            For the time being, I'm cheating on the EBNF by allowing
117            certain terms to be defined by POSIX character classes by
118            using the following syntax:
119
120              digit ::= [:digit:]
121
122            As far as I am aware, that's not valid EBNF.  Sue me.  I
123            didn't know how to write "char" otherwise (Unicode issues).
124            Suggestions welcome.
125        *)
126
127        tap            ::= version? { comment | unknown } leading_plan lines
128                           |
129                           lines trailing_plan {comment}
130
131        version        ::= 'TAP version ' positiveInteger {positiveInteger} "\n"
132
133        leading_plan   ::= plan skip_directive? "\n"
134
135        trailing_plan  ::= plan "\n"
136
137        plan           ::= '1..' nonNegativeInteger
138
139        lines          ::= line {line}
140
141        line           ::= (comment | test | unknown | bailout ) "\n"
142
143        test           ::= status positiveInteger? description? directive?
144
145        status         ::= 'not '? 'ok '
146
147        description    ::= (character - (digit | '#')) {character - '#'}
148
149        directive      ::= todo_directive | skip_directive
150
151        todo_directive ::= hash_mark 'TODO' ' ' {character}
152
153        skip_directive ::= hash_mark 'SKIP' ' ' {character}
154
155        comment        ::= hash_mark {character}
156
157        hash_mark      ::= '#' {' '}
158
159        bailout        ::= 'Bail out!' {character}
160
161        unknown        ::= { (character - "\n") }
162
163        (* POSIX character classes and other terminals *)
164
165        digit              ::= [:digit:]
166        character          ::= ([:print:] - "\n")
167        positiveInteger    ::= ( digit - '0' ) {digit}
168        nonNegativeInteger ::= digit {digit}
169

SUBCLASSING

171       Please see "SUBCLASSING" in TAP::Parser for a subclassing overview.
172
173       If you really want to subclass TAP::Parser's grammar the best thing to
174       do is read through the code.  There's no easy way of summarizing it
175       here.
176

SEE ALSO

178       TAP::Object, TAP::Parser, TAP::Parser::Iterator, TAP::Parser::Result,
179
180
181
182perl v5.12.4                      2011-06-07         TAP::Parser::Grammar(3pm)
Impressum