1.3.1 Types

The grammar rule for a minilang type name consists of three types that are represented by the keywords int , bool and void .

type int | bool | void

These are represented by minilang tokens INT, BOOL and VOID that are contained by the token module minilang.token .

To create a Soul parser that can parse the type production I have created a parser file that contains a parser module. The parser module imports the token module. Because token definitions are not needed by the interface of the parser, import statement contains an [implementation] prefix that instructs the parser generator to place the import to the generated .cpp file.

The parser itself is contained by a parser declaration that contains a rule for representing the type production. The body of the rule consists of a choice parsing expression that contains the choices for tokens INT, BOOL and VOID.

// type_parser.parser:

export module minilang.parser.type;

[implementation]import minilang.token;

parser TypeParser
{
    Type 
        ::= INT
        |   BOOL
        |   VOID
        ;
}

Next I have created a C++ module that contains abstract syntax tree node classes for the parsed types.

// ast.ixx:

export module minilang.ast;

// ...

class Node
{
    // ...
};

class IntNode : public Node
{
    // ...
};

class BoolNode : public Node
{
    // ...
};

class VoidNode : public Node
{
    // ...
};

Now the parser can be completed to create and return abstract syntax tree nodes for the types.

Each parser needs at least one lexer statement for instantiating the parser with a lexer.

I have also added module imports for the ast and lexer modules.

The C++ type of the value that the rule returns is specified after the name of the rule separated by the : symbol. I have created a C++ compound statement that creates and returns the corresponding syntax tree node for the tokens. Most parsing expressions can be associated such a semantic action that comes immediately after the parsing expression it is associated with.

export module minilang.parser.type;

[implementation]import minilang.ast;
[implementation]import minilang.lexer;
[implementation]import minilang.token;

parser TypeParser
{
    lexer minilang::lexer::MinilangLexer<char32_t>;

    Type : minilang::ast::Node*
        ::= INT{ return new minilang::ast::IntNode(); }
        |   BOOL{ return new minilang::ast::BoolNode(); }
        |   VOID{ return new minilang::ast::VoidNode(); }
        ;
}