~ubuntu-branches/ubuntu/trusty/c++-annotations/trusty

« back to all changes in this revision

Viewing changes to yo/concrete/lexer.yo

  • Committer: Package Import Robot
  • Author(s): tony mancill, Frank B. Brokken, tony mancill
  • Date: 2012-02-28 00:50:21 UTC
  • mfrom: (1.1.19)
  • Revision ID: package-import@ubuntu.com-20120228005021-sz7nnodntkvgh7qf
Tags: 9.2.1-1
[ Frank B. Brokken ]
* New upstream release (using flexc++, reauthored polymorphic semantic
  values and unrestricted unions). Upstream release 9.2.0 is implied by
  this release.

[ tony mancill ]
* Set Standards-Version to 3.9.3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
    The code associated with the i(regular expression) rules is located inside
2
 
the class ti(yyFlexLexer). However, we of course want to use the derived
3
 
class's members in this code. This causes a small problem. How does a
4
 
base-class member know about members of classes derived from it?
5
 
 
6
 
Inheritance helps us to overcome this problem. In the specification of
7
 
the class tt(yyFlexLexer), we notice that the function ti(yylex) is a
8
 
emi(virtual) function. The header file tt(FlexLexer.h) declares the
9
 
tt(virtual) member tt(int yylex):
10
 
        verb(
11
 
    class yyFlexLexer: public FlexLexer
12
 
    {
13
 
        public:
14
 
            yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 );
15
 
 
16
 
            virtual ~yyFlexLexer();
17
 
 
18
 
            void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
19
 
            struct yy_buffer_state* yy_create_buffer( istream* s, int size );
20
 
            void yy_delete_buffer( struct yy_buffer_state* b );
21
 
            void yyrestart( istream* s );
22
 
 
23
 
            virtual int yylex();
24
 
 
25
 
            virtual void switch_streams( istream* new_in, ostream* new_out );
26
 
    };
27
 
        )
28
 
    As this function is virtual it can be overridden by a em(derived)
29
 
class. In that case the overridden function is called from its base class
30
 
(i.e., tt(yyFlexLexer)) code. And as the derived class's tt(yylex) function
31
 
is called, it has access to the members of the derived class, and (of course)
32
 
also to the public and protected members of its base class.
33
 
 
34
 
    By default, the context in which the generated scanner is placed is the
35
 
function hi(yylex)tt(yyFlexLexer::yylex). This context changes if we use a
36
 
derived class, e.g., tt(Scanner). To derive tt(Scanner) from tt(yyFlexLexer),
37
 
generated by tt(flex), do as follows:
38
 
    itemization(
39
 
    it() The function tt(yylex) must be declared in the derived class
40
 
tt(Scanner).
41
 
    it() em(Options) (see below) are used to inform tt(flex) about the derived
42
 
class's name.
43
 
    )
 
1
    The function matching the i(regular expression) rules (tt(lex)) is a
 
2
member of the class ti(Scanner). Since tt(Scanner) is derived from
 
3
tt(ScannerBase), it has access to all of tt(ScannerBase)'s protected members
 
4
that execute the lexical scanner's regular expression matching algorithm.
 
5
 
44
6
 
45
7
    Looking at the regular expressions themselves, notice that we need rules
46
8
to recognize comment, ti(#include) directives, and all remaining characters.
47
 
This is all fairly standard practice. When an tt(#include) directive is
 
9
This all is fairly standard practice. When an tt(#include) directive is
48
10
sensed, the directive is parsed by the scanner. This too is common
49
11
practice. Our lexical scanner performs the following tasks:
50
12
    itemization(
51
13
    it() As usual, i(preprocessor directive)s are not
52
14
analyzed by a parser, but by the lexical scanner;
53
15
    it() The scanner uses a i(mini scanner) to extract the filename from the
54
 
directive, throwing a tt(Scanner::Error) value (tt(invalidInclude)) if this
55
 
fails;
56
 
    it() If the filename could be extracted, it is stored in tt(nextSource);
57
 
    it() When the tt(#include) directive has been processed, tt(pushSource) is
58
 
called to perform the switch to another file;
59
 
    it() When the end of the file (endOfFile()) is reached, the derived class's
60
 
member function tt(popSource) is called, popping the previously
61
 
pushed file and returning ti(true);
62
 
    it() Once the file-stack is empty, tt(popSource) returns ti(false),
63
 
resulting in calling tt(yyterminate), terminating the scanner.
 
16
directive, throwing a exception if this fails;
 
17
    it() If the filename could be extracted, processing switches to the next
 
18
stream, controlling for a maximum nesting depth.
 
19
    it() Once the end of the current file has been reached processing
 
20
automatically returns to the previous file, restoring the previous file name
 
21
an line number. The scanner returns 0 if all files have been processed.
64
22
    )