C言語解釈器-6テストプログラムから


次に、構文解析と実行をテストするテストプログラムのコードを示します.コードはその機能を説明できるはずです.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace SharpCTest
{
    using System.Diagnostics;
    using System.IO;
    using SharpC;
    using SharpC.Grammar;

    class Program
    {
        private static DateTime m_timeComsumption;  //  : , 

        static void Main(string[] args)
        {
            TestParser(); //  
            //TestRun(); //  
        }

        //  
        public static void TestMem()
        {
            Memory memMng = new Memory("..\\..\\memory.dat");
            int num = 0;
            Random rnd = new Random((int)DateTime.Now.Ticks);
            int x = 0;

            do
            {
                int addr = memMng.Allocate(4); // 2 << rnd.Next(2));

                if (addr == 0)
                {
                    Debug.WriteLine("Memory exhaused.");
                    break;
                }

                //Debug.WriteLine(String.Format("Alloc: 0X{0:X8}", addr));
                num++;

                if (x % 10 == 0)
                {
                    memMng.Free(addr);
                }

                if (x == 65535)
                {
                    int used = memMng.TotalSize - memMng.AviableSize;
                    int total = memMng.TotalSize / (1024 * 1024);
                    int item = memMng.AllocatedItem > 1024 ? (memMng.AllocatedItem > (1024 * 1024) ? memMng.AllocatedItem / (1024 * 1024) : memMng.AllocatedItem / 1024) : memMng.AllocatedItem;


                    Debug.WriteLine("Usage: " + used / (used > 1024 * 1024 ? (1024 * 1024) : (used > 1024 ? 1024 : 1)) + ((used > 1024 * 1024 ? 'M' : (used > 1024 ? 'K' : 'B'))) + '/' +
                        total + "M Item:" + item + (memMng.AllocatedItem > 1024 ? memMng.AllocatedItem > (1024 * 1024) ? "M" : "K" : ""));
                    x = 0;
                }

                x++;
            } while (true);

            Debug.WriteLine("Block:" + memMng.BlockCount);
            Debug.WriteLine("total: " + num);
        }

        public static void TestParser()
        {
            SharpC mySharpC = new SharpC("..\\..\\ParseSample.txt");

            mySharpC.OnParsing += mySharpC_OnParsing;
            mySharpC.OnParsingWarning += mySharpC_OnParsingWarning;
            mySharpC.OnParsingError += mySharpC_OnParsingError;
            mySharpC.OnBeforeParse += mySharpC_OnBeforeParse;
            mySharpC.OnAfterParse += mySharpC_OnAfterParse;

            mySharpC.Parse();
        }

        public static void TestRun()
        {
            SharpC mySharpC = new SharpC("..\\..\\ExecSample.txt");

            //mySharpC.OnParsing += mySharpC_OnParsing;
            mySharpC.OnParsingWarning += mySharpC_OnParsingWarning;
            mySharpC.OnParsingError += mySharpC_OnParsingError;
            //mySharpC.OnBeforeParse += mySharpC_OnBeforeParse;
            //mySharpC.OnAfterParse += mySharpC_OnAfterParse;
            mySharpC.OnBeforeRun += mySharpC_OnBeforeRun;
            mySharpC.OnAfterRun += mySharpC_OnAfterRun;

            mySharpC.Run();
        }

        static void mySharpC_OnBeforeRun(object sender, Context e)
        {
            m_timeComsumption = DateTime.Now;

            Debug.WriteLine("
================================ Program Begin ================================
"); } static void mySharpC_OnAfterRun(object sender, Context e) { Debug.WriteLine("
================================ Program End ================================
"); Debug.WriteLine(string.Format("Time consumption: {0} sec
", (DateTime.Now - m_timeComsumption).TotalSeconds)); } static void mySharpC_OnParsing(object sender, Parser.ParsingEventArg e) { Debug.WriteLine(string.Format("{0}:\t{1}", e.Context.GetType().UnderlyingSystemType, (sender as Parser).GetSourceByLocation(e.Context.Location) )); } static void mySharpC_OnParsingWarning(object sender, Parser.ParsingWarningEventArg e) { Debug.WriteLine(string.Format("{0}>>{1}", (sender as Parser).WarningCount, (sender as Parser).FormatErrorMessage(e.Location, Parser.ParsingErrorType.Warning, e.Description))); } static void mySharpC_OnParsingError(object sender, Parser.ParsingErrorEventArg e) { Debug.WriteLine(string.Format("{0}>>{1}", (sender as Parser).ErrorCount, (sender as Parser).FormatErrorMessage(e.Location, e.Error, e.Description))); e.Continue = true; } static void mySharpC_OnBeforeParse(object sender, Parser e) { m_timeComsumption = DateTime.Now; } static void mySharpC_OnAfterParse(object sender, Parser e) { Debug.WriteLine(string.Format("Time consumption: {0} sec
", (DateTime.Now - m_timeComsumption).TotalSeconds)); (sender as SharpC).Context.Print(); } } }

SharpCの実現は以下の通りである.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace SharpC
{
    using Grammar;

    public class SharpC
    {
        private Context m_context = null;
        private Parser m_parser = new Parser();
        private string m_path = string.Empty;
        private bool m_lastParsingResult = false;

        public event EventHandler<Parser.ParsingEventArg> OnParsing;
        public event EventHandler<Parser.ParsingWarningEventArg> OnParsingWarning;
        public event EventHandler<Parser.ParsingErrorEventArg> OnParsingError;
        public event EventHandler<Parser> OnBeforeParse;
        public event EventHandler<Parser> OnAfterParse;
        public event EventHandler<Context> OnBeforeRun;
        public event EventHandler<Context> OnAfterRun;

        public Context Context
        {
            get { return m_context; }
        }

        public Parser Parser
        {
            get { return m_parser; }
        }

        public SharpC()
        {
        }

        public SharpC(string path)
        {
            m_path = path;
        }

        public bool Parse()
        {
            return Parse(m_path);
        }

        public bool Parse(string path)
        {
            m_path = path;

            SourceCode src = new SourceCode();

            src.LoadFromFile(path);

            m_parser.OnParsing += OnParsing;
            m_parser.OnParsingWarning += OnParsingWarning;
            m_parser.OnParsingError += OnParsingError;

            if (OnBeforeParse != null)
            {
                OnBeforeParse(this, m_parser);
            }

            m_context = m_parser.Parse(src);

            bool res = m_parser != null;

            if (OnAfterParse != null)
            {
                OnAfterParse(this, m_parser);
            }

            m_lastParsingResult = res;

            return res;
        }

        public void Run(bool forceReparsing = false)
        {
            if (!m_lastParsingResult || forceReparsing)
                Parse();

            if (m_context != null)
            {
                if (OnBeforeRun != null)
                    OnBeforeRun(this, m_context);

                m_context.Run(m_context);

                if (OnAfterRun != null)
                    OnAfterRun(this, m_context);
            }
        }

        public void Run(string path)
        {
            if (Parse(path))
                Run();
        }
    }
}