Ratforプリプロセッサー -- 字句解析
2017-05-13


Ratforで書かれたプログラムからtokenを切り出すのは、defineやmacroと同様であるが、 引用符の通り扱いに注意が必要である。引用符は、ほとんどの場合ペアで使われ、その間に NEWLINEが入ることはない。この点に配慮する必要がある。

Ratofor版は以下の通り。

# gtoken.f -- get token for ratfor
      include ratfor.def
      character function gtoken(lexstr,toksiz)
      integer toksiz
      character lexstr(toksiz)
      character ngetc,type
      integer i
      character c

      include cline.ri

      while (ngetc(c) != EOF)
          if ((c != BLANK) & (c != TAB))
              break
      call putbak(c)
      for(i = 1;i < toksiz-1;i = i +1) {
          gtoken = type(ngetc(lexstr(i)))
          if ((gtoken != LETTER) & (gtoken != DIGIT))
              break
          }
      if (i >= toksiz-1)
          call synerr('token too long.')
      if (i > 1)
          call putbak(lexstr(i))
          lexstr(i) = EOS
          gtoken = ALPHA
      else if ((lexstr(1) == SQUOTE) | (lexstr(1) == DQUOTE))
          for (i = 2;ngetc(lexstr(i)) != lexstr(1)) {
              if (lexstr(i) == NEWLINE) {
                  call synerr('missing quote.')
                  lexstr(i) = lexstr(1)
                  call putbak(NEWLINE)
                  break
                  }
              }
      else if (lexstr(1) == SHARP) { # strip comments
          while (ngetc(lexstr(1)) != NEWLINE)
              ;
          gtoken = NEWLINE
          }
      lexstr(i+1) = EOS
      if (lexstr(1) == NEWLINE)
          linect = linect + 1
      return
      end

WATCOM Fortran77版は以下の通り。

c gtoken.f -- get token for ratfor
      include ratfor.def
      integer*1 function gtoken(lexstr,toksiz)
      integer toksiz
      integer*1 lexstr(toksiz)
      integer*1 ngetc,type
      integer i
      integer*1 c

      include cline.fi

      while (ngetc(c) .ne. EOF) do
          if ((c .ne. BLANK) .and. (c .ne. TAB)) then
              exit
          end if
      end while
      call putbak(c)
      i = 1
      while (i .lt. toksiz-1) do
          gtoken = type(ngetc(lexstr(i)))
          if ((gtoken .ne. LETTER) .and. (gtoken .ne. DIGIT)) then
              exit
          end if
          i = i + 1
      end while
      if (i .ge. toksiz-1) then
          call synerr('token too long.')
      end if
      if (i .gt. 1) then
          call putbak(lexstr(i))
          lexstr(i) = EOS
          gtoken = ALPHA
      else if (lexstr(1) .eq. SQUOTE .or. lexstr(1) .eq. DQUOTE) then
          i = 2
          while (ngetc(lexstr(i)) .ne. lexstr(1)) do
              if (lexstr(i) .eq. NEWLINE) then
                  call synerr('missing quote.')
                  lexstr(i) = lexstr(1)
                  call putbak(NEWLINE)
                  exit
              end if
              i = i + 1
          end while
      else if (lexstr(1) .eq. SHARP) then ! strip comments
          while (ngetc(lexstr(1)) .ne. NEWLINE) do
              ! nothing to do
          end while
          gtoken = NEWLINE
      end if
      lexstr(i+1) = EOS
      if (lexstr(1) .eq. NEWLINE) then
          linect = linect + 1
      end if
      return
      end

gtoken()の下請けルーチンsynerr()はsyntax errorを出力する。errorは、行番号とともに出力されるが、 行番号linectは、必要なモジュールで共有できるように、共通領域clineにおいている。

synerr()のRatofor版は以下の通り。

# synerr -- report Ratfor syntax error
      include ratfor.def
      subroutine synerr(msg)
      character msg(MAXLINE)
      character lc(MAXLINE)
      integer itoc
      integer junk

      include cline.ri

      call remark('error at line.')
      junk = itoc(linect,lc,MAXLINE)
      call putlin(lc,ERROUT)
      call fputc(ERROUT,COLON)
      call remark(msg)
      return
      end

WATCOM Fortran77版は以下の通り。

c synerr -- report Ratfor syntax error
      include ratfor.def
      subroutine synerr(msg)
      character msg(MAXLINE)
      integer*1 lc(MAXLINE)
      integer itoc
      integer junk

      include cline.fi

      call remark('error at line.')
      junk = itoc(linect,lc,MAXLINE)
      call putlin(lc,ERROUT)
      call fputc(ERROUT,BLANK)
      call remark(msg)
      return
      end

clineのRatofor版は以下の通り。

# cline.ri
      common /cline/linect
      integer linect
      data linect/1/

WATCOM Fortran77版は以下の通り。

c cline.fi
      common /cline/linect
      integer linect
      data linect/1/

gtoken()で切り出されたtokenは、次のlex()に引き継がれ解析される。 ここでも字句の判定に、lookup()を使用する。

lex()のRatfor版は以下の通り。



続きを読む

[コンピューター]
[RATFOR]

コメント(全1件)
コメントをする


記事を書く
powered by ASAHIネット