PreviousUpNext

15.3.26  src/app/yacc/lib/base.api

#  Mythryl-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi 

# Compiled by:
#     src/lib/std/standard.lib

# base.api: Base api file for Mythryl-Yacc.  This file contains apis that must
# be loaded before any of the files produced by Mythryl-Yacc are loaded



###                    When 'Omer smote 'is bloomin' lyre,
###                      He'd 'eard men sing by land an' sea;
###                        An' what he thought 'e might require,
###                          'E went an' took -- the same as me.
###
###                           -- Rudyard Kipling,
###                              Barrack-Room Ballads--Introduction



#  STREAM: api for a lazy stream.

api Stream {

      Stream( A_xa );

      streamify:  (Void -> X) -> Stream(X);
      cons:  (X, Stream(X)) -> Stream(X);
      get:  Stream(X) -> (X, Stream(X));
};

# LR_TABLE: api for an LR Table.
#  The list of actions and gotos passed to make_lr_table must be ordered by state
# number. The values for state 0 are the first in the list, the values for
#  state 1 are next, etc.


api Lr_Table {

         Pairlist (X,Y) = EMPTY
                              | PAIR  (X, Y, Pairlist (X,Y));

         State       =   STATE  Int;
         Terminal    =    TERM  Int;
         Nonterminal = NONTERM  Int;

         Action = SHIFT  State
                    | REDUCE  Int
                    | ACCEPT
                    | ERROR;

         Table;
        
         state_count:       Table -> Int;
         rule_count:        Table -> Int;
         describe_goto:     Table -> State -> Pairlist( Nonterminal, State );
         action:            Table -> (State, Terminal) -> Action;
         goto:              Table -> (State, Nonterminal) -> State;
         initial_state:      Table -> State;
         describe_actions:  Table -> State ->
                                 (Pairlist( Terminal, Action ), Action);

        exception GOTO  (State, Nonterminal);

         make_lr_table:  { actions:   Rw_Vector( (Pairlist( Terminal, Action ), Action)),
                         gotos:    Rw_Vector( Pairlist( Nonterminal, State ) ),
                         state_count:  Int, rule_count:  Int,
                         initial_state:  State } -> Table;
    };

# TOKEN: api revealing the internal package of a token. This api
# TOKEN distinct from the api { parser name }_TOKENS produced by Mythryl-Yacc.
#
# The { parser name }_TOKENS packages contain some types and functions to
#  construct tokens from values and positions.
#
# The representation of token was very carefully chosen here to allow the
# typeagnostic parser to work without knowing the types of semantic values
# or line numbers.
#
# This has had an impact on the TOKENS package produced by Mythryl-Yacc, which
# is a package parameter to lexer generics.  We would like to have some
# type Token(X) which functions to construct tokens would create.  A
# constructor function for a integer token might be
#
#  INT: (Int, X, X) -> Token(X)
#
# This is not possible because we need to have tokens with the representation
# given below for the typeagnostic parser.
#
#  Thus our constructur functions for tokens have the form:
#  INT: (Int, X, X) -> Token (Semantic_Value, X)
#  This in turn has had an impact on the api that lexers for Mythryl-Yacc
# must match and the types that a user must declare in the user declarations
# section of lexers.

                # Lr_Table      is from   src/app/yacc/lib/base.api
api Token {

        package lr_table:  Lr_Table;
        Token (X,Y) = TOKEN  (lr_table::Terminal, ((X, Y, Y)));
        same_token:   (Token (X, Y),  Token (X,Y)) -> Bool;
    };

#  LR_PARSER: api for a typeagnostic LR parser 

api Lr_Parser {
    #
    package stream:     Stream;         # Stream        is from   src/app/yacc/lib/base.api
    package lr_table:   Lr_Table;       # Lr_Table      is from   src/app/yacc/lib/base.api
    package token:      Token;          # Token         is from   src/app/yacc/lib/base.api

    sharing lr_table == token::lr_table;

    exception PARSE_ERROR;

    parse
      :
      { table:      lr_table::Table,
        lexer:      stream::Stream( token::Token (Y, Z) ),
        arg:        A_arg,
        void:       Y,

        saction
          :
          ( Int,
            Z ,
            List ((lr_table::State, ((Y, Z, Z)))), 
            A_arg
          )
          ->
          ( lr_table::Nonterminal,
            (Y, Z, Z),
            List(  (lr_table::State, (Y, Z, Z))  )
          ),


        error_recovery
          :
          { is_keyword:         lr_table::Terminal -> Bool,
            no_shift:           lr_table::Terminal -> Bool,
            #   
            preferred_change:   List( ( List lr_table::Terminal,
                                        List lr_table::Terminal
                                    ) ),

            errtermvalue:       lr_table::Terminal -> Y,
            show_terminal:      lr_table::Terminal -> String,

            terms:              List lr_table::Terminal,
            error:              (String, Z, Z) -> Void
          },

        lookahead:  Int  #  max amount of lookahead used in 
                         #  error correction 
      }
      ->
      ( Y,
        (stream::Stream( token::Token(Y, Z)))
      );
};

# Lexer: a api that most lexers produced for use with Mythryl-Yacc's
# output will match.  The user is responsible for declaring type Token,
# type Source_Position, and type Semantic_Value in the user_declarations section of a lexer.
#
# Note that type Token is abstract in the lexer.  This allows Mythryl-Yacc to
# create a TOKENS api for use with lexers produced by Mythryl-Lex that
# treats the type Token abstractly.  Lexers that are generics parametrized by
# a 'tokens' package matching a 'Tokens' api cannot examine the package
# of tokens.


api Lexer {
    #
    package user_declarations :
        api {
              Token( X, Y );
              Source_Position;
              Semantic_Value;
        };

     make_lexer:  (Int -> String) -> Void -> user_declarations::Token( user_declarations::Semantic_Value, user_declarations::Source_Position );
};

# ARG_LEXER: the %arg option of Mythryl-Lex allows users to produce lexers which
# also take an argument before yielding a function from Void to a token


api Arg_Lexer {
    #
    package user_declarations
        :
        api {
            Token( X, Y );
            Source_Position;
            Semantic_Value;
            Arg;
        };

    make_lexer
        :
        (Int -> String)
        ->
        user_declarations::Arg
        ->
        Void
        ->
        user_declarations::Token(
            user_declarations::Semantic_Value,
            user_declarations::Source_Position
        );
};

# Parser_Data: the api of parser_data packages in { parser name } lr_vals_fun
# produced by  Mythryl-Yacc.  All such packages match this api.  
#
# The { parser name } lr_vals_g produces a package which contains all the values
# except for the lexer needed to call the typeagnostic parser mentioned
# before.


api Parser_Data {

    Source_Position;            # The type of line numbers.
    Semantic_Value;                     # The type of semantic values.
    Arg;                                # The type of the user-supplied argument to the parser.

    # The intended type of the result of the parser.
    # This value is produced by applying 'extract'
    # from the package 'actions' to the final
    # semantic value resultiing from a parse:
    #
    Result;

    package lr_table:  Lr_Table;                # Lr_Table      is from   src/app/yacc/lib/base.api
    package token:  Token;                      # Token         is from   src/app/yacc/lib/base.api
    sharing token::lr_table == lr_table;

    # The 'actions' package contains the functions which
    # maintain the semantic values stack in the parser.
    # Void is used to provide a default value for the semantic stack.
    #
    package actions
        :
        api {
                actions
                    :
                    ( Int,
                      Source_Position,
                      List ( (lr_table::State, ((Semantic_Value, Source_Position, Source_Position)))),
                      Arg
                    )
                    ->
                    ( lr_table::Nonterminal,
                      (Semantic_Value, Source_Position, Source_Position),
                      (List ((lr_table::State, (Semantic_Value, Source_Position, Source_Position))))
                    );

                void:     Semantic_Value;
                extract:  Semantic_Value -> Result;
            };

    # Package 'error_recovery' contains information
    # used to improve error recovery in an
    # error-correcting parser:
    #
    package error_recovery
        :
        api {
           is_keyword:     lr_table::Terminal -> Bool;
           no_shift:       lr_table::Terminal -> Bool;
           errtermvalue:   lr_table::Terminal -> Semantic_Value;
           show_terminal:  lr_table::Terminal -> String;
           terms: List(    lr_table::Terminal );

           preferred_change:    List( ( List( lr_table::Terminal ),
                                        List( lr_table::Terminal )
                                    ) );
        };

    table:  lr_table::Table;            # The LR table for the parser.
};

# api PARSER is the api that most user parsers created by 
# Mythryl-Yacc will match.


api Parser {
    #
    package token:      Token;          # Token         is from   src/app/yacc/lib/base.api
    package stream:     Stream;         # Stream        is from   src/app/yacc/lib/base.api

    exception PARSE_ERROR;

    Source_Position;                    # Type Source_Position is the type of line numbers.
    Result;                             # Type Result is the type of the result from the parser.
    Arg;                                # The type of the user-supplied argument to the parser.


    Semantic_Value;                     # type Semantic_Value is the type of semantic values
                                        # for the semantic value stack

    make_lexer                          # make_lexer is used to create a stream of tokens for the parser 
        :
        (Int -> String)
        ->
        stream::Stream (token::Token (Semantic_Value, Source_Position) );

    # 'parse' takes a stream of tokens
    # and a function to print errors
    # and returns a Result and a stream
    # containing the unused tokens:
    #
    parse
        :
        ( Int,
          (stream::Stream( token::Token (Semantic_Value, Source_Position))),
          ((String, Source_Position, Source_Position) -> Void),
          Arg
        )
        ->
        ( Result,
          stream::Stream( token::Token (Semantic_Value, Source_Position))
        );

    same_token
        :
        ( token::Token (Semantic_Value, Source_Position),
          token::Token (Semantic_Value, Source_Position)
        )
        ->
        Bool;
};

# api Arg_Parser is the api that will be matched by parsers whose
#  lexer takes an additional argument.

api Arg_Parser {
    #
    package token:      Token;          # Token         is from   src/app/yacc/lib/base.api
    package stream:     Stream;         # Stream        is from   src/app/yacc/lib/base.api

    exception PARSE_ERROR;

    Arg;
    Lex_Arg;
    Source_Position;
    Result;
    Semantic_Value;

    make_lexer
        :
        (Int -> String)
        ->
        Lex_Arg
        ->
        stream::Stream( token::Token (Semantic_Value, Source_Position) );

    parse
        :
        ( Int,
          stream::Stream( token::Token (Semantic_Value, Source_Position) ),
          (String, Source_Position, Source_Position) -> Void,
          Arg
        )
        ->
        ( Result,
          stream::Stream (token::Token (Semantic_Value, Source_Position))
        );

    same_token
        :
        ( token::Token (Semantic_Value, Source_Position),
          token::Token (Semantic_Value, Source_Position)
        )
        ->
        Bool;
};


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext