【问题标题】:C# File stream reading strings (Coco/R Taste)C#文件流读取字符串(Coco/R Taste)
【发布时间】:2012-01-28 02:58:44
【问题描述】:

我正在使用 C# 中的 Coco R 示例 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 中的扩展操作: Filestream就是这样使用的

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;

并添加了使用文件流的大小写开关

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;

问题是,我在互联网上的任何地方都找不到读取字符串的方法, 显然ReadString(s) 的工作方式与ReadInt(s) 的工作方式不同。 我想知道是否可以帮助我找到一个从文件流中读取字符串的操作。

我之前没有做过任何文件流管理。

【问题讨论】:

    标签: c# filestream cocor


    【解决方案1】:

    EDIT3 再次查看这些东西后,我发现这种方法存在更大的问题。首先解释一下:Coco/R 从 atg 文件生成扫描器和解析器,Taste.cs 中的主程序使用它们来编译 Taste.TAS。

    编译后的 Taste.TAS 然后被输入 CodeGen.cs 的 Interpret 方法,该方法像虚拟机一样处理它接收到的操作码,所以它的 ReadInt() 方法应该从 Taste.IN 中读取,其中包含示例数据编译的 Taste.TAS 程序。

    因此,要在 CodeGen.cs 中添加对 hello world 的支持,仅更改 Interpret 方法是不够的,您还必须修补 Emit 方法,以允许编译器在编译时添加字符串-时间。

    Hacky 一如既往(进入 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, 
    }
    

    在 Taste.ATG 中,您必须将 Write-instruction 更改为 Gen.Emit(Op.WRITES, t.val);

    在解释方法中,你需要使用对字符串列表的引用:

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

    EDIT4 - 仅供参考 要从文件中读取字符串文字,您可以使用 StreamReader 类,如下所示:

        /// <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] 类,但由于默认情况下它仅适用于字符串,因此需要一些棘手的读取和查找操作来获取跨越多行的字符串(如果支持) ,因此您不会为程序的其余部分添加文件流。

    【讨论】:

    • 这是经过一些调整和添加后编译的,但它打印的结果只是一个“?”不管字符串的写是什么。
    • 又看了一遍,完全改了帖子:)
    • 除了编辑之外,如果我在 ATG 中打印我找到的字符串,它会在操作之前打印它,Coco 所做的事情(据我所知)是存储操作和然后一个一个地执行它们,所以当它看到“写“字符串”时它会读取“字符串”然后打印它
    • 好的,请澄清您的问题:您是否只想能够编写字符串文字?那么这就是你想要的答案。如果 otoh 您希望能够像整数一样读取和写入字符串,那么您必须首先为字符串定义一个类型并为其使用变量,除了字符串文字
    • 我得到了上面的编辑工作!!!谢谢 :) 这让我永远。您的方法与我的想法类似,只是我将以一种尴尬的方式实现它,我会先读取字符串并将其存储在字符串数组中,然后将其索引存储在堆栈中已经存在于codegen中。然后我会把它退回并打印出来。再次感谢你:)
    猜你喜欢
    • 1970-01-01
    • 2014-01-21
    • 1970-01-01
    • 1970-01-01
    • 2010-10-10
    • 2020-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多