2011-12-26 5 views
1

私はCoco RのサンプルテイストをC#で扱っています。C#File stream reading strings(Coco/R Taste)

操作は、このような

書き込みハロー世界

として与えられたとき、私は文字列を書くために、コードを拡張しようとしている

私は私が保存した文字列を記述することができる方法を、同定しました。私は私がいる問題のために、関連するコードを入れている:Taste.ATG

を拡大

| "write" 
    { Expr<out type> (. if (type != integer) SemErr("integer type expected"); 
          gen.Emit(Op.WRITE); .) 
    | '"' 
    ident  (. name = Convert.ToString(t.val); 
          gen.Emit(Op.READS); 
          gen.Emit(Op.WRITES).) 
    '"' 
    }';' 
CodeGen.csで

拡張操作: ファイルストリームは、このよう

public void Interpret (string data) { 
    int val; 
    try { 
     FileStream s = new FileStream(data, FileMode.Open); 
     Console.WriteLine(); 
     pc = progStart; stack[0] = 0; top = 1; bp = 0; 
に使用されています

と添加場合切り替え、その使用FILESTREAM

case Op.READ: val = ReadInt(s); Push(val); break; 
case Op.READS: stackString[index] = ReadString(s) ; Push(index); index++; break; 
case Op.WRITE: Console.WriteLine(Pop()); break; 
case Op.WRITES: Console.WriteLine(stackString[Pop()]); break; 

問題は、私はC、あります蟻は、インターネット上のどこでも文字列を読む方法を見つける、 明らかにReadString(s)は同じ方法で動作しませんReadInt(s)はありません。 ファイルストリームから文字列を読み取る操作を見つけるのに役立つかどうかは疑問でした。

私は以前にファイルストリーム管理を行っていません。

答えて

2

EDIT3 このようなことをもう一度調べたところ、このアプローチではさらに大きな問題が見つかりました。最初にいくつかの説明があります:Coco/Rはatgファイルからスキャナとパーサを生成し、Taste.csのメインプログラムはこれらを使ってTaste.TASをコンパイルします。

コンパイルされたTaste.TASは、CodeGen.csのInterpretメソッドに入力されます。このメソッドは、仮想マシンのように受け取るオペコードを処理します。したがって、ReadInt()メソッドは、Taste.INから読み取ることになっています。コンパイルされたTaste.TASプログラム。

このように、CodeGen.csでhelloワールドのサポートを追加するには、Interpretメソッドを変更するだけでは不十分です。また、Emitメソッドにパッチを適用して、コンパイラがコンパイル時に文字列を追加できるようにします-時間。いつものように

ハック(CodeGen.csに入る):味が

List<string> strStack = new List<string>(); 
public void Emit(Op op, string str) 
{ 
    int idx = strStack.Count; 
    strStack.Add(str); 
    Emit(op, idx); // adds the opcode, 
} 

。ATGは、あなたはGen.Emit(Op.WRITES, t.val);

に書き込み命令を変更する必要がありますし、解釈法では、あなたは文字列リストへの参照を使用する必要があります:

case Op.WRITES: Console.WriteLine(strStack[Next2()]); break; 

EDIT4 - ただ、今後の参考のため

/// <summary> 
    ///  Reads a string literal from a file, essentially implementing the regex pattern /\"{.*}\"/. 
    ///  Ignores escape characters (for instance, "\"" will fail) 
    /// </summary> 
    /// <param name="fs">The file stream to read from.</param> 
    /// <returns>The string literal without it's quotes upon success, null otherwise.</returns> 
    static string ReadString(FileStream fs) 
    { 
     if (!fs.CanRead) 
      return null; // cant read from stream, throw an exception here 

     var reader = new StreamReader(fs); 
     var sb = new StringBuilder(); 

     bool inString = false; 

     while (true) 
     { 
      if (reader.Peek() < 0) 
       return null; // reached EOF before string ended, throw exception here 

      char ch = (char)reader.Read(); 

      if (inString) 
       if (ch == '"') 
        break; 
       else 
        sb.Append(ch); 
      else 
       if (ch == '"') 
        inString = true; 
       else if (!char.IsWhiteSpace(ch)) 
        return null; // string does not start with quote, throw exception here 
     } 

     return sb.ToString(); 
    } 

代替は[Regex] [3]クラスを使用することですが、それ以来、dで:ファイルから文字列リテラルを読むには、あなたはそうのようなStreamReaderクラスを使用することができますefaultは文字列でしか動作しません。複数の行(サポートされている場合)に文字列を読み込むためには、読みやすくてシークな操作が必要なので、プログラムの残りの部分についてはファイルストリームをフューバリングしません。

+0

これはツイートして追加した後にコンパイルされますが、印刷結果は単なる「?」です。文字列の書き込みが何であっても。 – DustBunny

+0

は、再び記事を見て、完全に投稿を変更しました。編集の他に –

+0

もあります。私はそれを見つけるとATGの文字列を印刷すると、それはアクションの前に印刷されます。 )は、オペレーションを格納し、次にそれらを1つずつ実行するので、 "書き込み"文字列 ""を見ると "文字列"を読み取って印刷します。 – DustBunny