Developer's guide

For Grammar_.h, Lexer_.h

logical view

See Lexer_ UML diagram and Grammar_ UML diagram.

Implementation note : Token_'s generated by the Lexer_ are disposed of by the SyntacticSink (or the Grammar_). However, objects of the derived class terminalToken's are static and need not be disposed of (so allocation/deallocation is reduced). So deallocation is done by a virtual member function toGarbage(), overriden as required. It can deallocate child objects, then destroy the object by the instruction 'delete this; return' (!). Because of such a allocation/deallocation scheme, Token_ should not be allocated as variables local to a function; use static or dynamic allocation instead.

dynamic view

These sequence diagrams applies for the example in user's guide. They show function calls stack in each object lane.

1. This one shows SyntacticTree construction for 'var;;' :

Grammar_        |TokenSource
lane            |lane

parseFromTo()
  root_->parse_()
    EITHER()->parse_()
      variable_->parse_()
        SyntacticTree s1()
        MAYBE()->parse_()
          int_->parse_()
                |currentSource.expect_( int_) returns false
            returns errorToken
        s1.push_back( noToken);
        identifier_->parse_()
                |currentSource.expect_( identifier_) returns true
        s1.push_back( currentSource.fetch_() returns VariableToken( "identifier", "var"))
        semicolon_->parse_()
                |currentSource.expect_( semicolon_) returns true
        s1.push_back( currentSource.fetch_() returns semicolon_)
        HANDLE_()
          syntacticSink->handle( s1)  output occurs here
        return noToken
      returns noToken
    EITHER()->parse_()
      variable_->parse_()
        SyntacticTree s1()
        MAYBE()->parse_()
          int_->parse_()
                |currentSource.expect_( int_) returns false
        s1.push_back( noToken);
        identifier_->parse_()
                |currentSource.expect_( identifier_) returns false
          return errorToken
        return errorToken
      function_->parse_()
        SyntacticTree s1()
        identifier_->parse_()
                |currentSource.expect_( identifier_) returns false
          return errorToken
        return errorToken
      returns errorToken
    returns noToken
  currentSource->printWarning()

2. This sequence diagram shows for 'foo3(){;}' :

Grammar_        |TokenSource
lane            |lane

parseFromTo()
                |expecteds()
  root_->parse_()
    EITHER->parse_()
      variable_->parse_()
        SyntacticTree s1()
        MAYBE()->parse_()
                |currentSource.expect_( int_)
                |  expecteds.insert( int_)
                |  return false;
        identifier_->parse_()
                |currentSource.expect_( identifier_) return false
                |currentSource.fetch_()
                |  expecteds.clear()
        semicolon_->parse_()
                |currentSource.expect_( semicolon_)
                |  expecteds.insert( semicolon_)
                |  return false
        //s1==SyntacticTree( noToken, VariableToken( "identifier", "foo3"), 0)
                |currentSource.storeBack( s1)
        returns errorToken
      function_->parse_()
        SyntacticTree s1()
                |currentSource.expect_( identifier_)
                |currentSource.fetch_()   .. from data stored back
                |currentSource.expect_( braces_)
                |currentSource.fetch_()
                |  expecteds.clear()   Since we found braces, we no longer care that semicolon was not found
        ANY()->parse_()
          variable_->parse_()
            SyntacticTree s2()
            MAYBE()->parse_()
                |currentSource.expect_( int_)
                |  expecteds.insert( int_)
                |  return false
            identifier_.parse_()
                |currentSource.expect_( identifier_)
                |  expecteds.insert( identifier_)
                |  return false
            //s2= SyntacticTree( noToken, 0)
                |currentSource.storeBack( s2)
            return errorToken
          return noToken
        endBraces->parse_()
                |currentSource.expect_( endBraces)
                |  expecteds.insert( endBraces)
                |  return false;
        //s1=SyntacticTree( VariableToken( "identifier", "foo3"), braces, 0)
                |currentSource.storeBack( s1)
        returns errorToken
      returns errorToken
    returns errorToken
                |//expecteds= set( int_, identifier, endBraces)
  cuurentSource->printWarning()