;;;; mother modular generic compiler project
; (c)2001,2002/GPL Oskar Schirmer <oskar@scara.com>
; see file COPYING for GPL license details

; finite automaton scanner description for ansi c (preprocessor)
; according to Harbison and Steele, "C A Reference Manual", ISBN 0-13-110933-2

; note 1: trigraph expansion must be done prior
; note 2: line splicing (backslash newline) must be done prior
; note 3: escape character evaluation in constants is not done by the scanner

(finite-automaton
  '(
    (initial
      ((#\space #\newline #\tab #\return #\page)
                    #f get  #f initial     #f)
      (#\#          #f get pos initialhash #f)
      (#\/         #t  get pos initialslas #f)
      (else         #f  #f  #f inline      #f)
    )
    (initialhash
      (#\#          #f get  #f inline      doublehash)
      (else         #f  #f  #f inprep      hashmark)
    )
    (initialslas
      (#\*          #f get  #f initialcomm #f)
      (else         #f  #f  #f slash       #f)
    )
    (initialcomm
      (#\*          #f get  #f initialcome #f)
      (else         #f get  #f initialcomm #f)
    )
    (initialcome
      (#\/          #f get  #f initial     #f)
      (#\*          #f get  #f initialcome #f)
      (else         #f get  #f initialcomm #f)
    )
    (inprep
      ((#\newline #\return)
                    #f get pos initial     linebreak)
      ((#\space #\tab #\page)
                    #f get  #f inprep      #f)
      (#\/         #t  get pos inprepslash #f)
      ((#\a . #\z) #t  get pos incommand  #f)
      (else         #f  #f  #f pinline     #f)
    )
    (inprepslash
      (#\*          #f get  #f inprepcomm  #f)
      (else         #f  #f  #f pslash       #f)
    )
    (inprepcomm
      (#\*          #f get  #f inprepcomme #f)
      (else         #f get  #f inprepcomm  #f)
    )
    (inprepcomme
      (#\/          #f get  #f inprep      #f)
      (#\*          #f get  #f inprepcomme #f)
      (else         #f get  #f inprepcomm  #f)
    )
    (incommand
      (#\e         #t  get  #f incommande #f)
      ((#\A . #\Z) #t  get  #f incommand  #f)
      ((#\a . #\z) #t  get  #f incommand  #f)
      ((#\_ #\$)   #t  get  #f incommand  #f)
      ((#\0 . #\9) #t  get  #f incommand  #f)
      (else         #f  #f  #f pinline    prepcommand)
    )
    (incommande
      (#\e         #t  get  #f incommande #f)
      ((#\space #\tab #\page #\/ #\<)
                    #f  #f  #f inprep2     prepcommand)
      (else         #f  #f  #f incommand  #f)
    )
    (inprep2
      ((#\newline #\return)
                    #f get pos initial     linebreak)
      ((#\space #\tab #\page)
                    #f get  #f inprep2     #f)
      (#\/         #t  get pos inprep2slas #f)
      (#\<          #f get pos includestr  #f)
      ((#\a . #\z) #t  get pos incommand2 #f)
      ((#\A . #\Z) #t  get pos incommand2 #f)
      ((#\_ #\$)   #t  get pos incommand2 #f)
      (else         #f  #f  #f pinline      #f)
    )
    (inprep2slas
      (#\*          #f get  #f inprep2comm #f)
      (else         #f  #f  #f pslash       #f)
    )
    (inprep2comm
      (#\*          #f get  #f inprep2come #f)
      (else         #f get  #f inprep2comm #f)
    )
    (inprep2come
      (#\/          #f get  #f inprep2     #f)
      (#\*          #f get  #f inprep2come #f)
      (else         #f get  #f inprep2comm #f)
    )
    (includestr
      ((#\newline #\return)
                    #f  #f  #f initial     "missing > at end of file name")
      (#\>          #f get  #f pinline      includestring)
      (else        #t  get  #f includestr  #f)
    )
    (incommand2
      ((#\A . #\Z) #t  get  #f incommand2 #f)
      ((#\a . #\z) #t  get  #f incommand2 #f)
      ((#\_ #\$)   #t  get  #f incommand2 #f)
      ((#\0 . #\9) #t  get  #f incommand2 #f)
      (#\(          #f get  #f pinline      wordwithlparen)
      (else         #f  #f  #f pinline      prepword)
    )

    (pinline
      ((#\newline #\return)
                    #f get pos initial     linebreak)
      ((#\space #\tab #\page)
                    #f get  #f pinline      #f)
      (#\#          #f get pos phashmark    #f)
      (#\!         #t  get pos pexclamation #f)
      (#\%         #t  get pos ppercent     #f)
      (#\^         #t  get pos pcircumflex  #f)
      (#\&         #t  get pos pampersand   #f)
      (#\*         #t  get pos pasterisk    #f)
      (#\-         #t  get pos pminus       #f)
      (#\+         #t  get pos pplus        #f)
      (#\=         #t  get pos pequal       #f)
      (#\~         #t  get pos pinline      binarynot)
      (#\|         #t  get pos pverticalbar #f)
      (#\.         #t  get pos pperiod      #f)
      (#\<         #t  get pos pless        #f)
      (#\>         #t  get pos pgreater     #f)
      (#\/         #t  get pos pslash       #f)
      (#\?          #f get pos pinline      question)
      (#\(          #f get pos pinline      lparen)
      (#\)          #f get pos pinline      rparen)
      (#\[          #f get pos pinline      lbracket)
      (#\]          #f get pos pinline      rbracket)
      (#\{          #f get pos pinline      lbrace)
      (#\}          #f get pos pinline      rbrace)
      (#\,          #f get pos pinline      comma)
      (#\;          #f get pos pinline      semicolon)
      (#\:          #f get pos pinline      colon)
      ((#\A . #\K) #t  get pos pword        #f)
      (#\L          #f get pos pl           #f)
      ((#\M . #\Z) #t  get pos pword        #f)
      ((#\a . #\z) #t  get pos pword        #f)
      ((#\_ #\$)   #t  get pos pword        #f)
      (#\0         #t  get pos pnull        #f)
      ((#\1 . #\9) #t  get pos pdigit       #f)
      (#\"          #f get pos pstring      #f)
      (#\'          #f get pos pcharacter   #f)
      (else         #f  #f  #f #f           #f)
    )
    (phashmark
      (#\#          #f get  #f pinline      doublehash)
      (else         #f  #f  #f pinline      hashmark)
    )
    (pexclamation
      (#\=         #t  get  #f pinline      compare)
      (else         #f  #f  #f pinline      logicalnot)
    )
    (ppercent
      (#\=         #t  get  #f pinline      assignment)
      (else         #f  #f  #f pinline      modulo)
    )
    (pcircumflex
      (#\=         #t  get  #f pinline      assignment)
      (else         #f  #f  #f pinline      binaryxor)
    )
    (pampersand
      (#\=         #t  get  #f pinline      assignment)
      (#\&         #t  get  #f pinline      logicaland)
      (else         #f  #f  #f pinline      ampersand)
    )
    (pasterisk
      (#\=         #t  get  #f pinline      assignment)
      (else         #f  #f  #f pinline      asterisk)
    )
    (pminus
      (#\=         #t  get  #f pinline      assignment)
      (#\-         #t  get  #f pinline      decrement)
      (#\>         #t  get  #f pinline      pointer)
      (else         #f  #f  #f pinline      add)
    )
    (pplus
      (#\=         #t  get  #f pinline      assignment)
      (#\+         #t  get  #f pinline      increment)
      (else         #f  #f  #f pinline      add)
    )
    (pequal
      (#\=         #t  get  #f pinline      compare)
      (else         #f  #f  #f pinline      be)
    )
    (pverticalbar
      (#\=         #t  get  #f pinline      assignment)
      (#\|         #t  get  #f pinline      logicalor)
      (else         #f  #f  #f pinline      binaryor)
    )
    (pperiod
      ((#\0 . #\9) #t  get  #f pnumfract    #f)
      (else         #f  #f  #f pinline      period)
    )
    (pless
      (#\=         #t  get  #f pinline      relational)
      (#\<         #t  get  #f pshift       #f)
      (else         #f  #f  #f pinline      relational)
    )
    (pgreater
      (#\=         #t  get  #f pinline      relational)
      (#\>         #t  get  #f pshift       #f)
      (else         #f  #f  #f pinline      relational)
    )
    (pshift
      (#\=         #t  get  #f pinline      assignment)
      (else         #f  #f  #f pinline      shift)
    )
    (pslash
      (#\=         #t  get  #f pinline      assignment)
      (#\*          #f get  #f pcomment     #f)
      (else         #f  #f  #f pinline      divide)
    )
    (pword
      ((#\A . #\Z) #t  get  #f pword        #f)
      ((#\a . #\z) #t  get  #f pword        #f)
      ((#\_ #\$)   #t  get  #f pword        #f)
      ((#\0 . #\9) #t  get  #f pword        #f)
      (else         #f  #f  #f pinline      prepword)
    )
    (pnull
      ((#\X #\x)   #t  get  #f pintegerhex  #f)
      ((#\0 . #\7) #t  get  #f pintegeroct  #f)
      ((#\8 . #\9) #t  get  #f pnumber      #f)
      (#\.         #t  get  #f pnumfract    #f)
      ((#\e #\E)   #t  get  #f pnumexpon    #f)
      ((#\u #\U)   #t  get  #f pintegeru    #f)
      ((#\l #\L)   #t  get  #f pintegerl    #f)
      (else         #f  #f  #f pinline      integer)
    )
    (pdigit
      ((#\0 . #\9) #t  get  #f pdigit       #f)
      (#\.         #t  get  #f pnumfract    #f)
      ((#\e #\E)   #t  get  #f pnumexpon    #f)
      ((#\u #\U)   #t  get  #f pintegeru    #f)
      ((#\l #\L)   #t  get  #f pintegerl    #f)
      (else         #f  #f  #f pinline      integer)
    )
    (pintegerhex
      ((#\0 . #\9) #t  get  #f pintegerhex2 #f)
      ((#\A . #\F) #t  get  #f pintegerhex2 #f)
      ((#\a . #\f) #t  get  #f pintegerhex2 #f)
      (else        #t   #f  #f #f "error in hexadecimal constant")
    )
    (pintegerhex2
      ((#\0 . #\9) #t  get  #f pintegerhex2 #f)
      ((#\A . #\F) #t  get  #f pintegerhex2 #f)
      ((#\a . #\f) #t  get  #f pintegerhex2 #f)
      ((#\u #\U)   #t  get  #f pintegeru    #f)
      ((#\l #\L)   #t  get  #f pintegerl    #f)
      (else         #f  #f  #f pinline      integer)
    )
    (pintegeroct
      ((#\0 . #\7) #t  get  #f pintegeroct  #f)
      ((#\8 . #\9) #t  get  #f pnumber      #f)
      (#\.         #t  get  #f pnumfract    #f)
      ((#\e #\E)   #t  get  #f pnumexpon    #f)
      ((#\u #\U)   #t  get  #f pintegeru    #f)
      ((#\l #\L)   #t  get  #f pintegerl    #f)
      (else         #f  #f  #f pinline      integer)
    )
    (pintegeru
      ((#\l #\L)   #t  get  #f pinline      integer)
      (else         #f  #f  #f pinline      integer)
    )
    (pintegerl
      ((#\u #\U)   #t  get  #f pinline      integer)
      (else         #f  #f  #f pinline      integer)
    )
    (pnumber
      ((#\0 . #\9) #t  get  #f pnumber      #f)
      (#\.         #t  get  #f pnumfract    #f)
      ((#\e #\E)   #t  get  #f pnumexpon    #f)
      (else        #t   #f  #f #f "error in floating point constant")
    )
    (pnumfract
      ((#\0 . #\9) #t  get  #f pnumfract    #f)
      ((#\e #\E)   #t  get  #f pnumexpon    #f)
      ((#\f #\F #\l #\L)
                   #t  get  #f pinline      number)
      (else         #f  #f  #f pinline      number)
    )
    (pnumexpon
      ((#\0 . #\9) #t  get  #f pnumexpon3   #f)
      ((#\- #\+)   #t  get  #f pnumexpon2   #f)
      (else        #t   #f  #f #f "error in floating point constant")
    )
    (pnumexpon2
      ((#\0 . #\9) #t  get  #f pnumexpon3   #f)
      (else        #t   #f  #f #f "error in floating point constant")
    )
    (pnumexpon3
      ((#\0 . #\9) #t  get  #f pnumexpon3   #f)
      ((#\f #\F #\l #\L)
                   #t  get  #f pinline      number)
      (else         #f  #f  #f pinline      number)
    )
    (pstring
      (#\"          #f get  #f pinline      string)
      (#\\         #t  get  #f pstringesc   #f)
      ((#\newline #\return)
                    #f  #f  #f #f "string must not contain newline")
      (else        #t  get  #f pstring      #f)
    )
    (pstringesc
      (else        #t  get  #f pstring      #f)
    )
    (pl
      (#\"          #f get  #f plstring     #f)
      (#\'          #f get  #f pcharacter   #f)
      (else        #\L  #f  #f pword        #f)
    )
    (plstring
      (#\"          #f get  #f pinline      lstring)
      (#\\         #t  get  #f plstringesc  #f)
      ((#\newline #\return)
                    #f  #f  #f #f "string must not contain newline")
      (else        #t  get  #f plstring     #f)
    )
    (plstringesc
      (else        #t  get  #f plstring     #f)
    )
    (pcharacter
      (#\'          #f get  #f pinline      character)
      (#\\         #t  get  #f pcharesc     #f)
      ((#\newline #\return)
                    #f  #f  #f #f "character must not contain newline")
      (else        #t  get  #f pcharacter   #f)
    )
    (pcharesc
      (else        #t  get  #f pcharacter   #f)
    )
    (pcomment
      (#\*          #f get  #f pcommentend  #f)
      (else         #f get  #f pcomment     #f)
    )
    (pcommentend
      (#\/          #f get  #f pinline      #f)
      (#\*          #f get  #f pcommentend  #f)
      (else         #f get  #f pcomment     #f)
    )

    (inline
      ((#\newline #\return)
                    #f get pos initial     linebreak)
      ((#\space #\tab #\page)
                    #f get  #f inline      #f)
      (#\#          #f get pos hashmark    #f)
      (#\!         #t  get pos exclamation #f)
      (#\%         #t  get pos percent     #f)
      (#\^         #t  get pos circumflex  #f)
      (#\&         #t  get pos ampersand   #f)
      (#\*         #t  get pos asterisk    #f)
      (#\-         #t  get pos minus       #f)
      (#\+         #t  get pos plus        #f)
      (#\=         #t  get pos equal       #f)
      (#\~         #t  get pos inline      binarynot)
      (#\|         #t  get pos verticalbar #f)
      (#\.         #t  get pos period      #f)
      (#\<         #t  get pos less        #f)
      (#\>         #t  get pos greater     #f)
      (#\/         #t  get pos slash       #f)
      (#\?          #f get pos inline      question)
      (#\(          #f get pos inline      lparen)
      (#\)          #f get pos inline      rparen)
      (#\[          #f get pos inline      lbracket)
      (#\]          #f get pos inline      rbracket)
      (#\{          #f get pos inline      lbrace)
      (#\}          #f get pos inline      rbrace)
      (#\,          #f get pos inline      comma)
      (#\;          #f get pos inline      semicolon)
      (#\:          #f get pos inline      colon)
      ((#\A . #\K) #t  get pos word        #f)
      (#\L          #f get pos l           #f)
      ((#\M . #\Z) #t  get pos word        #f)
      ((#\a . #\z) #t  get pos word        #f)
      ((#\_ #\$)   #t  get pos word        #f)
      (#\0         #t  get pos null        #f)
      ((#\1 . #\9) #t  get pos digit       #f)
      (#\"          #f get pos string      #f)
      (#\'          #f get pos character   #f)
      (else         #f  #f  #f #f          #f)
    )
    (hashmark
      (#\#          #f get  #f inline      doublehash)
      (else         #f  #f  #f inline      hashmark)
    )
    (exclamation
      (#\=         #t  get  #f inline      compare)
      (else         #f  #f  #f inline      logicalnot)
    )
    (percent
      (#\=         #t  get  #f inline      assignment)
      (else         #f  #f  #f inline      modulo)
    )
    (circumflex
      (#\=         #t  get  #f inline      assignment)
      (else         #f  #f  #f inline      binaryxor)
    )
    (ampersand
      (#\=         #t  get  #f inline      assignment)
      (#\&         #t  get  #f inline      logicaland)
      (else         #f  #f  #f inline      ampersand)
    )
    (asterisk
      (#\=         #t  get  #f inline      assignment)
      (else         #f  #f  #f inline      asterisk)
    )
    (minus
      (#\=         #t  get  #f inline      assignment)
      (#\-         #t  get  #f inline      decrement)
      (#\>         #t  get  #f inline      pointer)
      (else         #f  #f  #f inline      add)
    )
    (plus
      (#\=         #t  get  #f inline      assignment)
      (#\+         #t  get  #f inline      increment)
      (else         #f  #f  #f inline      add)
    )
    (equal
      (#\=         #t  get  #f inline      compare)
      (else         #f  #f  #f inline      be)
    )
    (verticalbar
      (#\=         #t  get  #f inline      assignment)
      (#\|         #t  get  #f inline      logicalor)
      (else         #f  #f  #f inline      binaryor)
    )
    (period
      ((#\0 . #\9) #t  get  #f numfract    #f)
      (else         #f  #f  #f inline      period)
    )
    (less
      (#\=         #t  get  #f inline      relational)
      (#\<         #t  get  #f shift       #f)
      (else         #f  #f  #f inline      relational)
    )
    (greater
      (#\=         #t  get  #f inline      relational)
      (#\>         #t  get  #f shift       #f)
      (else         #f  #f  #f inline      relational)
    )
    (shift
      (#\=         #t  get  #f inline      assignment)
      (else         #f  #f  #f inline      shift)
    )
    (slash
      (#\=         #t  get  #f inline      assignment)
      (#\*          #f get  #f comment     #f)
      (else         #f  #f  #f inline      divide)
    )
    (word
      ((#\A . #\Z) #t  get  #f word        #f)
      ((#\a . #\z) #t  get  #f word        #f)
      ((#\_ #\$)   #t  get  #f word        #f)
      ((#\0 . #\9) #t  get  #f word        #f)
      (else         #f  #f  #f inline      word)
    )
    (null
      ((#\X #\x)   #t  get  #f integerhex  #f)
      ((#\0 . #\7) #t  get  #f integeroct  #f)
      ((#\8 . #\9) #t  get  #f number      #f)
      (#\.         #t  get  #f numfract    #f)
      ((#\e #\E)   #t  get  #f numexpon    #f)
      ((#\u #\U)   #t  get  #f integeru    #f)
      ((#\l #\L)   #t  get  #f integerl    #f)
      (else         #f  #f  #f inline      integer)
    )
    (digit
      ((#\0 . #\9) #t  get  #f digit       #f)
      (#\.         #t  get  #f numfract    #f)
      ((#\e #\E)   #t  get  #f numexpon    #f)
      ((#\u #\U)   #t  get  #f integeru    #f)
      ((#\l #\L)   #t  get  #f integerl    #f)
      (else         #f  #f  #f inline      integer)
    )
    (integerhex
      ((#\0 . #\9) #t  get  #f integerhex2 #f)
      ((#\A . #\F) #t  get  #f integerhex2 #f)
      ((#\a . #\f) #t  get  #f integerhex2 #f)
      (else        #t   #f  #f #f "error in hexadecimal constant")
    )
    (integerhex2
      ((#\0 . #\9) #t  get  #f integerhex2 #f)
      ((#\A . #\F) #t  get  #f integerhex2 #f)
      ((#\a . #\f) #t  get  #f integerhex2 #f)
      ((#\u #\U)   #t  get  #f integeru    #f)
      ((#\l #\L)   #t  get  #f integerl    #f)
      (else         #f  #f  #f inline      integer)
    )
    (integeroct
      ((#\0 . #\7) #t  get  #f integeroct  #f)
      ((#\8 . #\9) #t  get  #f number      #f)
      (#\.         #t  get  #f numfract    #f)
      ((#\e #\E)   #t  get  #f numexpon    #f)
      ((#\u #\U)   #t  get  #f integeru    #f)
      ((#\l #\L)   #t  get  #f integerl    #f)
      (else         #f  #f  #f inline      integer)
    )
    (integeru
      ((#\l #\L)   #t  get  #f inline      integer)
      (else         #f  #f  #f inline      integer)
    )
    (integerl
      ((#\u #\U)   #t  get  #f inline      integer)
      (else         #f  #f  #f inline      integer)
    )
    (number
      ((#\0 . #\9) #t  get  #f number      #f)
      (#\.         #t  get  #f numfract    #f)
      ((#\e #\E)   #t  get  #f numexpon    #f)
      (else        #t   #f  #f #f "error in floating point constant")
    )
    (numfract
      ((#\0 . #\9) #t  get  #f numfract    #f)
      ((#\e #\E)   #t  get  #f numexpon    #f)
      ((#\f #\F #\l #\L)
                   #t  get  #f inline      number)
      (else         #f  #f  #f inline      number)
    )
    (numexpon
      ((#\0 . #\9) #t  get  #f numexpon3   #f)
      ((#\- #\+)   #t  get  #f numexpon2   #f)
      (else        #t   #f  #f #f "error in floating point constant")
    )
    (numexpon2
      ((#\0 . #\9) #t  get  #f numexpon3   #f)
      (else        #t   #f  #f #f "error in floating point constant")
    )
    (numexpon3
      ((#\0 . #\9) #t  get  #f numexpon3   #f)
      ((#\f #\F #\l #\L)
                   #t  get  #f inline      number)
      (else         #f  #f  #f inline      number)
    )
    (string
      (#\"          #f get  #f inline      string)
      (#\\         #t  get  #f stringesc   #f)
      ((#\newline #\return)
                    #f  #f  #f #f "string must not contain newline")
      (else        #t  get  #f string      #f)
    )
    (stringesc
      (else        #t  get  #f string      #f)
    )
    (l
      (#\"          #f get  #f lstring     #f)
      (#\'          #f get  #f character   #f)
      (else        #\L  #f  #f word        #f)
    )
    (lstring
      (#\"          #f get  #f inline      lstring)
      (#\\         #t  get  #f lstringesc  #f)
      ((#\newline #\return)
                    #f  #f  #f #f "string must not contain newline")
      (else        #t  get  #f lstring     #f)
    )
    (lstringesc
      (else        #t  get  #f lstring     #f)
    )
    (character
      (#\'          #f get  #f inline      character)
      (#\\         #t  get  #f charesc     #f)
      ((#\newline #\return)
                    #f  #f  #f #f "character must not contain newline")
      (else        #t  get  #f character   #f)
    )
    (charesc
      (else        #t  get  #f character   #f)
    )
    (comment
      (#\*          #f get  #f commentend  #f)
      (else         #f get  #f comment     #f)
    )
    (commentend
      (#\/          #f get  #f inline      #f)
      (#\*          #f get  #f commentend  #f)
      (else         #f get  #f comment     #f)
    )
  )
)
