Subversion Repositories tendra.SVN

Rev

Rev 5 | Blame | Compare with Previous | Last modification | View Log | RSS feed

%prefixes%

terminal = lex_ ;


%maps%


/*
    ENTRY POINT

    The main entry point for the grammar is given by unit.
*/

unit -> read_lex ;


/*
    TYPE MAPPINGS

    These mappings give the correspondences between syntax types and
    C types.
*/

BOOL -> int ;
CHARACTERS -> SID_CHARS ;
IDENTIFIER -> SID_STRING ;
STRING -> SID_STRING ;

%header% @{
/*
                 Crown Copyright (c) 1997
    
    This TenDRA(r) Computer Program is subject to Copyright
    owned by the United Kingdom Secretary of State for Defence
    acting through the Defence Evaluation and Research Agency
    (DERA).  It is made available to Recipients with a
    royalty-free licence for its use, reproduction, transfer
    to other parties and amendment for any purpose not excluding
    product development provided that any such use et cetera
    shall be deemed to be acceptance of the following conditions:-
    
        (1) Its Recipients shall ensure that this Notice is
        reproduced upon any copies or amended versions of it;
    
        (2) Any amended version of it shall be clearly marked to
        show both the nature of and the organisation responsible
        for the relevant amendment or amendments;
    
        (3) Its onward transfer from a recipient to another
        party shall be deemed to be that party's acceptance of
        these conditions;
    
        (4) DERA gives no warranty or assurance as to its
        quality or suitability for any purpose and DERA accepts
        no liability whatsoever in relation to any use to which
        it may be put.
*/


#include "config.h"
#include "char.h"
#include "error.h"
#include "lex.h"
#include "syntax.h"
#include "xalloc.h"


/*
    PARSER TYPES

    These types give the implementation of the types used in the syntax.
*/

typedef letter *SID_CHARS ;
typedef char *SID_STRING ;


/*
    SID IDENTIFIER PREFIX

    This string is added to the start of each sid identifier.
*/

char *sid_prefix = "lex_" ;


/*
    CURRENT CONDITIONAL

    This variable is used to record the current conditional.
*/

static char *crt_cond = NULL ;


/*
    COMPILATION MODE

    We allow unreached code in the automatically generated sections.
*/

#if FS_TENDRA
#pragma TenDRA begin
#ifndef OLD_PRODUCER
#pragma TenDRA unreachable code allow
#endif
#endif


@}, @{
/*
                 Crown Copyright (c) 1997
    
    This TenDRA(r) Computer Program is subject to Copyright
    owned by the United Kingdom Secretary of State for Defence
    acting through the Defence Evaluation and Research Agency
    (DERA).  It is made available to Recipients with a
    royalty-free licence for its use, reproduction, transfer
    to other parties and amendment for any purpose not excluding
    product development provided that any such use et cetera
    shall be deemed to be acceptance of the following conditions:-
    
        (1) Its Recipients shall ensure that this Notice is
        reproduced upon any copies or amended versions of it;
    
        (2) Any amended version of it shall be clearly marked to
        show both the nature of and the organisation responsible
        for the relevant amendment or amendments;
    
        (3) Its onward transfer from a recipient to another
        party shall be deemed to be that party's acceptance of
        these conditions;
    
        (4) DERA gives no warranty or assurance as to its
        quality or suitability for any purpose and DERA accepts
        no liability whatsoever in relation to any use to which
        it may be put.
*/


#ifndef SYNTAX_INCLUDED
#define SYNTAX_INCLUDED

extern char *sid_prefix ;

@};


%terminals%


/*
    IDENTIFIER TERMINAL

    This action gives the terminal for identifiers.  The identifier text
    is built up in token_buff by the lexical routines.
*/

identifier : () -> ( i : IDENTIFIER ) = @{
    @i = xstrcpy ( token_buff ) ;
@} ;


/*
    SID IDENTIFIER TERMINAL

    This action gives the terminal for sid-style identifiers.  The
    identifier text is built up in token_buff by the lexical routines.
*/

sid-identifier : () -> ( i : IDENTIFIER ) = @{
    int n ;
    char *s ;
    char buff [1000] ;
    strcpy_v ( buff, sid_prefix ) ;
    n = ( int ) strlen ( buff ) ;
    for ( s = token_buff ; *s ; s++ ) {
        if ( *s == '-' ) {
            buff [ n++ ] = '_' ;
            buff [ n++ ] = 'H' ;
        } else if ( *s == '_' ) {
            buff [ n++ ] = '_' ;
            buff [ n++ ] = '_' ;
        } else {
            buff [ n++ ] = *s ;
        }
        if ( n >= 900 ) {
            error ( ERROR_SERIOUS, "Identifier too long" ) ;
            break ;
        }
    }
    buff [n] = 0 ;
    @i = xstrcpy ( buff ) ;
@} ;


/*
    STRING TERMINAL

    This action gives the terminal for strings.  The string text is built
    up in token_buff by the lexical routines.
*/

string : () -> ( s : STRING ) = @{
    @s = xstrcpy ( token_buff ) ;
@} ;


/*
    SPECIAL STRING TERMINALS

    These actions give a number of special strings.
*/

upper : () -> ( s : STRING ) =  @{ @s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ; @} ;
lower : () -> ( s : STRING ) =  @{ @s = "abcdefghijklmnopqrstuvwxyz" ; @} ;
digit : () -> ( s : STRING ) =  @{ @s = "0123456789" ; @} ;


%actions%


/*
    CONCATENATE TWO STRINGS

    This action concatenates two strings.
*/

<string-concat> : ( a : STRING, b : STRING ) -> ( s : STRING ) = @{
    @s = xstrcat ( @a, @b ) ;
@} ;


/*
    CREATE A CHARACTER STRING

    This action maps an input string into its internal representation
    as an array of character codes.
*/

<make-chars> : ( s : STRING ) -> ( c : CHARACTERS ) = @{
    @c = make_string ( @s ) ;
@} ;


/*
    SET WHITE SPACE VARIABLE

    This action sets the white space variable to the given array of
    characters.  There is a check to make sure that it has not already
    been set.
*/

<make-white> : ( s : CHARACTERS ) -> () = @{
    if ( white_space ) {
        error ( ERROR_SERIOUS, "White space group already defined" ) ;
    }
    white_space = @s ;
@} ;


/*
    CREATE A CHARACTER GROUP

    This action defines the character group i to be s.
*/

<make-group> : ( i : IDENTIFIER, s : CHARACTERS ) -> () = @{
    make_group ( @i, @s ) ;
@} ;


/*
    CREATE A PRE-PASS MAPPING

    This action creates a pre-pass mapping from s to t.
*/

<make-trigraph> : ( s : CHARACTERS, t : STRING ) -> () = @{
    char *data [3] ;
    data [0] = @t ;
    data [1] = NULL ;
    data [2] = crt_cond ;
    add_char ( pre_pass, @s, data ) ;
@} ;


/*
    CREATE A MAIN-PASS MAPPING

    This action creates a main-pass mapping from s to the lexical token i.
*/

<make-token> : ( s : CHARACTERS, i : IDENTIFIER, b : BOOL ) -> () = @{
    char *data [3] ;
    data [0] = @i ;
    data [1] = ( @b ? "()" : NULL ) ;
    data [2] = crt_cond ;
    add_char ( main_pass, @s, data ) ;
@} ;


/*
    CREATE A KEYWORD

    This action creates a keyword called s.
*/

<make-keyword> : ( s : STRING, i : IDENTIFIER, b : BOOL ) -> () = @{
    char *data [3] ;
    data [0] = @i ;
    data [1] = ( @b ? "()" : NULL ) ;
    data [2] = crt_cond ;
    add_keyword ( @s, data ) ;
@} ;


/*
    ADD A CONDITION

    This action adds i to the current condition.
*/

<add-condition> : ( i : IDENTIFIER ) -> () = @{
    if ( crt_cond ) {
        crt_cond = xstrcat ( crt_cond, xstrcat ( " && ", @i ) ) ;
    } else {
        crt_cond = @i ;
    }
@} ;


/*
    COMPLEMENT CONDITION

    This action complements the current condition.
*/

<compl-condition> : () -> () = @{
    if ( crt_cond ) {
        if ( strchr ( crt_cond, '&' ) ) {
            crt_cond = xstrcat ( xstrcat ( "!( ", crt_cond ), " )" ) ;
        } else {
            crt_cond = xstrcat ( "!", crt_cond ) ;
        }
    }
@} ;


/*
    GET CONDITION

    This action gets the current condition.
*/

<get-condition> : () -> ( i : IDENTIFIER ) = @{
    @i = crt_cond ;
@} ;


/*
    SET CONDITION

    This action sets the current condition.
*/

<set-condition> : ( i : IDENTIFIER ) -> () = @{
    crt_cond = @i ;
@} ;


/*
    BOOLEANS

    These actions give the booleans true and false.
*/

<true> : () -> ( b : BOOL ) =   @{ @b = 1 ; @} ;
<false> : () -> ( b : BOOL ) =  @{ @b = 0 ; @} ;


/*
    SYNTAX ERROR

    This action reports a syntax error.
*/

<syntax-error> : () -> () = @{
    error ( ERROR_SERIOUS, "Syntax error" ) ;
@} ;


%trailer% @{
@}, @{
#endif
@} ;