Version 0 of XDR

Updated 2004-06-08 15:45:06 by CMCc

#! /bin/sh

    # \
    exec itclsh "$0" ${1+"$@"}

    # Generate Lexical Analyzer for XDR - xdr-lex.tcl
    lappend auto_path /usr/local/lib
    package require yeti
    package require ylex

    set xdr_lex [yeti::ylex \#auto -name xdr_lexer]
    $xdr_lex macro \
        OCOMM {/[*]} \
        CCOMM {[*]/} \
        WS        {[ \t\f]} \
        D        {[0-9]} \
        LD        {[\.0-9]} \
        E        {[DEde][+-]?[0-9]+} \
        IDS        {[a-zA-Z]} \
        IDCH        {[a-zA-Z0-9_.$]} \
        INT        {[-]?[0-9]+} \
        LT        {[<]} \
        GT        {[>]} \
        OR        {[|]} \
        DOT        {[.]} \
        STAR        {[*]} \
        CARET        {\^} \
        LP        {[(]} \
        RP        {[)]} \
        STRING {"([^"]|"")*"} \
        EOL        {\n} \
        other        {.} \
        HASH        {#} \
        LBRACKET {\[} \
        RBRACKET {\]} \
        LBRACE {\{} \
        RBRACE {\}} \
        LP {[(]} \
        RP {[)]} \
        SEMI {[;]} \
        COLON {[:]} \
        EQUAL {[=]} \
        COMMA {[,]}

    $xdr_lex code public {
        variable lineno 0
    }

    $xdr_lex code reset {
        set lineno 0
    }

    $xdr_lex add -state INITIAL <OCOMM> {
            #puts stderr "COMMENT"
            set yystate COMMENT
    }
    $xdr_lex add -state COMMENT <CCOMM> {
            #puts stderr "END COMMENT"
            set yystate INITIAL
    }
    $xdr_lex add -state COMMENT . {
    }

    $xdr_lex add -state INITIAL {\n<WS>+} {}

    $xdr_lex add -state INITIAL \n {
        # ignore new lines - don't combine with white space
        incr lineno;
    }

    $xdr_lex add -state INITIAL <WS>+ {
        # ignore white space
    }

    $xdr_lex add -state INITIAL <INT> {
       return [list INT $yytext]
    }

    # add special character macros
    foreach ch {
        LBRACE RBRACE LT GT LBRACKET RBRACKET LP RP
        COMMA EQUAL SEMI COLON STAR INT
    } {
        $xdr_lex add -state INITIAL [list <${ch}>] [list return S_$ch]
    }

    set reserved {
        opaque string void
        unsigned int hyper float double quadruple bool
        enum struct union
        switch case default
        const typedef
    }

        #foreach char [split $word {}] {
            #append pattern \[[string toupper $char]$char\]
        #}

    # add reserved words
    foreach word $reserved {
        $xdr_lex add -state INITIAL -nocase ${word} \
            "return \[list S_[string toupper $word]]"
    }

    $xdr_lex add -state INITIAL <IDCH>+ {
        return [list S_ID [string trim $yytext]]
    }

    # generate the scanner code to stdout
    puts [$xdr_lex dump]
    delete object $xdr_lex

   #! /bin/sh
    # \
    exec itclsh "$0" ${1+"$@"}

    if { [info script] == "$::argv0" } {
        lappend auto_path [pwd]
    }

    # Lexical analyzer for XDR.
    lappend auto_path /usr/local/lib
    package require yeti
    package require ylex

    set xdr_parser [eval yeti::yeti \#auto -name xdr_parser -start specification -verbose 4]

    $xdr_parser code public {
        method getstate {} {
            return [list $yystate $yylhs]
        }
        public variable yyterm ""
    }

    $xdr_parser code error {
        upvar yyterm yyterm
        #puts stderr "Error: $yyerrmsg / $yyterm"
    }

    $xdr_parser add {
    specification        {definition specification} {return [list $1 $2]}
    | definition {}

    definition        constdef        {}
    | typedef {return $1}

    constant        INT        {return $1}

    constdef        {S_CONST S_ID S_EQUAL constant S_SEMI} {
        return [CONST $2 $4]
    }

    assign {S_ID S_EQUAL value} {return [concat [list $1] [list $3]]}

    assignments assign {}
    | {assignments S_COMMA assign} {return [concat $1 $3]}

    enumbody {S_LBRACE assignments S_RBRACE} {
        return $2
    }

    declarations {declaration S_SEMI} {return [list $1]}
    |        {declaration S_SEMI declarations} {return [concat [list $1] $3]}

    structbody {S_LBRACE declarations S_RBRACE} {
        return $2
    }

    unionbody {S_SWITCH S_LP declaration S_RP S_LBRACE cases S_RBRACE} {
        return [concat [list $3] $6]
    }

    typedef        {S_TYPEDEF declaration S_SEMI} {return [SEM TYPEDEF $2]}
    |        {S_ENUM S_ID enumbody S_SEMI} {return [eval SEM ENUM $2 $3]}
    |        {S_STRUCT S_ID structbody S_SEMI} {return [eval SEM STRUCT $2 $3]}
    |        {S_UNION S_ID unionbody S_SEMI} {return [eval SEM UNION $2 $3]}

    typespec        S_BOOL {return [SCALAR BOOL]}
    |        S_FLOAT {return [SCALAR FLOAT]}
    |        S_DOUBLE {return [SCALAR DOUBLE ]}
    |        S_QUADRUPLE {return [SCALAR QUADRUPLE]}
    |        S_INT {return [SCALAR INT]}
    |        S_HYPER {return [SCALAR HYPER]}
    |        {S_UNSIGNED S_INT} {return [SCALAR INT UNSIGNED]}
    |        {S_UNSIGNED S_HYPER} {return [SCALAR HYPER UNSIGNED]}
    |        {S_ENUM enumbody} {return [SEM A_ENUM $2]}
    |        {S_STRUCT structbody} {return [SEM A_STRUCT $2]}
    |        {S_UNION unionbody} {return [SEM A_UNION $2]}
    |        S_ID {return $1}

    value        constant {return $1}
    |        S_ID {return [CONST_LOOKUP $1]}

    value_or_nil value        {return $1}
    |        {}        {return ""}

    declaration        S_VOID {
        return [SEM VOID]
    }
    |        {S_STRING S_ID S_LT value_or_nil S_GT} {
        return [eval SEM STRING $2 $4]
    }
    |        {S_OPAQUE S_ID S_LT value_or_nil S_GT} {
        return [eval SEM OPAQUE_VECTOR $2 $4]
    }
    |        {S_OPAQUE S_ID S_LBRACKET value S_RBRACKET} {
        return [SEM OPAQUE $2 $4]
    }
    |        {typespec S_STAR S_ID} {
        return [SEM OPTIONAL $1 $3]
    }
    |        {typespec S_ID S_LT value_or_nil S_GT} {
        return [eval SEM TYPE $1 $2 $4]
    }
    |        {typespec S_ID S_LBRACKET value S_RBRACKET} {
        return [SEM VECTOR $1 $2 $4]
    }
    |        {typespec S_ID} {
        return [SEM DECLARE $2 $1]
    }

    case_value        constant {return $1}
    |        S_ID {return [list CASE $1]}

    case        {S_CASE case_value S_COLON declaration S_SEMI} {
        return [concat [list $2] [list $4]]
    }

    defcase        {S_DEFAULT S_COLON declaration S_SEMI} {
        return [concat "" [list $3]]
    }

    cases        case {
        return $1
    }
    |        {case cases} {
        return [concat $1 $2]
    }
    |        {case defcase} {
        return [concat $1 $2]
    }

    }

    #
    # generate the parser code to stdout
    #
    puts [$xdr_parser dump]
    delete object $xdr_parser