次へ: 10 最後に 上へ: C のソースからプロトタイプ宣言を作成 前へ: 8 状況を保存するアルゴリズム (PDF ファイル: awktg.pdf)


9 ソースコード全体

後は、「保存」、「リセット」、「出力」などの部分を作成すれば済みますが、 行の保存は、例えば
  h[++lines]=$0
のようにすればいいでしょう。 そしてこの ``lines'' という変数で現在保存している行数を管理すれば、 リセットも ``lines=0''、および必要ならばフラグのクリアで済みます。

現在保存している行があるかどうかも、 この ``lines'' の値を見ればいいだけ (正ならば保存している行がある) ですし、出力部分もこれを利用すれば、

  for(j=1;j<lines;j++) print h[j]
  print h[lines] ";"
でできます。

また、「ア」$\sim$「オ」のパターンは、正規表現を使って、以下のように書けます。

これで今までの疑似コードをすべて具体的なコードとして書くことができます。 それらを上げてみます。

まず、単純なアルゴリズムの場合 (cf. 6 節):

  {
      while(1){
          if($0 !~ /^[_a-zA-Z].*\(/) next
          lines=0; h[++lines]=$0
          while(1){
              if($0 ~ /\)[ \t]*$/){
                  getline
                  if($0 ~ /^\{[ \t]*$/){
                      for(j=1;j<lines;j++) print h[j]
                      print h[lines] ";"
                      next
                  }
                  else break
              }
              else if($0 ~ /;[ \t]*$/) next
              else{
                  getline
                  if($0 !~ /^[ \t]/) break
                  h[++lines]=$0
              }
          }
      }
  }

次は、パターンマッチ中心のコード (cf. 7 節):

  { flag1=0 }
  /^[_a-zA-Z].*\(/ {
      lines=0; flag2=0; h[++lines]=$0
      flag1=1
  }
  /^[ \t]/ {
      if(lines>0){ h[++lines]=$0; flag1=1 }
      else{ lines=0; flag2=0; next }
  }
  /^\{[ \t]*$/ {
      if(flag2==1){ 
          for(j=1;j<lines;j++) print h[j]
          print h[lines] ";"
      }
      lines=0; flag2=0 
      next
  } 
  /\)[ \t]*$/ { if(flag1==1) flag2=1; next }
  (flag1==0){ lines=0; flag2=0 }

また、この無駄を省いたもの:

  { flag1=0 }
  {
      if($0 ~ /^[_a-zA-Z].*\(/){ 
          lines=0; flag2=0; h[++lines]=$0
          flag1=1
      }
      else if($0 ~ /^[ \t]/){
          if(lines>0){ h[++lines]=$0; flag1=1 }
          else{ lines=0; flag2=0; next }
      }
      else if($0 ~ /^\{[ \t]*$/){
          if(flag2==1){ 
              for(j=1;j<lines;j++) print h[j]
              print h[lines] ";"
          }
          lines=0; flag2=0
          next;
      }
  } 
  /\)[ \t]*$/{ if(flag1==1) flag2=1; next }
  (flag1==0){ lines=0; flag2=0 }

および、いっそ一つのブロックで書いたもの:

  {
      flag1=0
      if($0 ~ /^[_a-zA-Z].*\(/){ 
          lines=0; flag2=0; h[++lines]=$0
          flag1=1;
      }
      else if($0 ~ /^[ \t]/){
          if(lines>0){ h[++lines]=$0; flag1=1 }
          else{ lines=0; flag2=0; next }
      }
      else if($0 ~ /^\{[ \t]*$/){
          if(flag2==1){ 
              for(j=1;j<lines;j++) print h[j]
              print h[lines] ";"
          }
          lines=0; flag2=0
          next;
      }
      if(/\)[ \t]*$/){ if(flag1==1) flag2=1; next }
      if(flag1==0){ lines=0; flag2=0 }
  }

そして状態を保存するアルゴリズムの場合 (cf. 8 節):

  /^[_a-zA-Z].*\(/ { lines=0; h[++lines]=$0; mode=1 }
  (mode==1 || mode==2){
      if($0 ~ /^[ \t]/) h[++lines]=$0
      else if(mode!=1){ mode=0; next }
      if($0 ~ /\)[ \t]*$/) mode=3
      else if($0 ~ /;[ \t]*$/) mode=0
      else mode=2
      next
  }
  (mode==3){
      if($0 ~ /^\{[ \t]*$/){ 
          for(j=1;j<lines;j++) print h[j]
          print h[lines] ";"
      }
      mode=0
  }

それの例外処理を先にしたもの:

  /^[_a-zA-Z].*\(/ { lines=0; h[++lines]=$0; mode=1 }
  (mode==0){ next }
  (mode==3){
      if($0 ~ /^\{[ \t]*$/){ 
          for(j=1;j<lines;j++) print h[j]
          print h[lines] ";"
      }
      mode=0
      next
  }
  {
      if($0 ~ /^[ \t]/) h[++lines]=$0
      else if(mode!=1){ mode=0; next }
      if($0 ~ /\)[ \t]*$/) mode=3
      else if($0 ~ /;[ \t]*$/) mode=0
      else mode=2
  }


次へ: 10 最後に 上へ: C のソースからプロトタイプ宣言を作成 前へ: 8 状況を保存するアルゴリズム
竹野茂治@新潟工科大学
2006年6月22日