19、Tokenizer

Tokenizer

该项目使用一个接口和类层次结构来模拟读取C#源文件和将源文件分类为各种标记(标识、关键字和操作符等)。作为一个用法示例,它还从关键的接口派生类以便以彩色语法的形式在一个富文本框内显示标记。

(1) 创建项目

创建WPF Application项目:Tokenizer

(2) 添加资源

添加TokenInterface文件夹,并在其中添加Interface文件:IVisitable.csIToken.csITokenVisitor.csIVisitableToken.cs

添加TokenClass文件夹,并在其中添加Class文件:DefaultTokenImpl.csIdentifierToken.csKeywordToken.csOperatorToken.csPunctuatorToken.csStringLiteralToken.csWhitespaceToken.cs

添加Class文件:ColorSyntaxVisitor.csSourceFile.cs

(3) 设计界面

 

<Window x:Class="Tokenizer.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="Color Syntax" Height="300" Width="500">

    <Grid>

        <RichTextBox Name="richTextBoxCodeText" Margin="10,10,10,40" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">

            <RichTextBox.Resources>

                <Style TargetType="{x:Type Paragraph}">

                    <Setter Property="Margin" Value="0"/>

                </Style>

            </RichTextBox.Resources>

        </RichTextBox>

        <Button Name="buttonOpen" Margin="0,0,0,10" Width="65" Height="23" HorizontalAlignment="Center" VerticalAlignment="Bottom" Content="Open" Click="buttonOpen_Click" />

    </Grid>

</Window>

(4) 修改IVisitable.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace Tokenizer. TokenInterface

{

    interface IVisitable

    {

        void Accept(ITokenVisitor visitor);

    }

}

(5) 修改IToken.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace Tokenizer. TokenInterface

{

    interface IToken

    {

        string ToString();

    }

}

(6) 修改ITokenVisitor.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace Tokenizer.TokenInterface

{

    interface ITokenVisitor

    {

        void VisitComment(string token);

        void VisitIdentifier(string token);

        void VisitKeyword(string token);

        void VisitOperator(string token);

        void VisitPunctuator(string token);

        void VisitStringLiteral(string token);

        void VisitWhitespace(string token);

    }

}

(7) 修改IVisitableToken.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace Tokenizer.TokenInterface

{

    interface IVisitableToken : IVisitable, IToken

    {

 

    }

}

(8) 修改DefaultTokenImpl.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace Tokenizer.TokenClass

{

    abstract class DefaultTokenImpl

    {

        private readonly string name;

 

        protected DefaultTokenImpl(string name)

        {

            this.name = name;

        }

 

        public new string ToString()

        {

            return this.name;

        }

    }

}

(9) 修改IdentifierToken.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Tokenizer.TokenInterface;

 

namespace Tokenizer.TokenClass

{

    class IdentifierToken : DefaultTokenImpl, IVisitableToken

    {

        public IdentifierToken(string name)

            : base(name)

        {

        }

 

        void IVisitable.Accept(ITokenVisitor visitor)

        {

            visitor.VisitIdentifier(this.ToString());

        }

    }

}

(10) 修改KeywordToken.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Tokenizer.TokenInterface;

 

namespace Tokenizer.TokenClass

{

    class KeywordToken : DefaultTokenImpl, IVisitableToken

    {

        public KeywordToken(string name)

            : base(name)

        {

        }

 

        void IVisitable.Accept(ITokenVisitor visitor)

        {

            visitor.VisitKeyword(this.ToString());

        }

    }

}

(11) 修改OperatorToken.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Tokenizer.TokenInterface;

 

namespace Tokenizer.TokenClass

{

    class OperatorToken : DefaultTokenImpl, IVisitableToken

    {

        public OperatorToken(string name)

            : base(name)

        {

        }

 

        void IVisitable.Accept(ITokenVisitor visitor)

        {

            visitor.VisitOperator(this.ToString());

        }

    }

}

(12) 修改PunctuatorToken.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Tokenizer.TokenInterface;

 

namespace Tokenizer.TokenClass

{

    class PunctuatorToken : DefaultTokenImpl, IVisitableToken

    {

        public PunctuatorToken(string name)

            : base(name)

        {

        }

 

        void IVisitable.Accept(ITokenVisitor visitor)

        {

            visitor.VisitPunctuator(this.ToString());

        }

    }

}

(13) 修改StringLiteralToken.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Tokenizer.TokenInterface;

 

namespace Tokenizer.TokenClass

{

    class StringLiteralToken : DefaultTokenImpl, IVisitableToken

    {

        public StringLiteralToken(string name)

            : base(name)

        {

        }

 

        void IVisitable.Accept(ITokenVisitor visitor)

        {

            visitor.VisitStringLiteral(this.ToString());

        }

    }

}

(14) 修改WhitespaceToken.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Tokenizer.TokenInterface;

 

namespace Tokenizer.TokenClass

{

    class WhitespaceToken : DefaultTokenImpl, IVisitableToken

    {

        public WhitespaceToken(string name)

            : base(name)

        {

        }

 

        void IVisitable.Accept(ITokenVisitor visitor)

        {

            visitor.VisitWhitespace(this.ToString());

        }

    }

}

(15) 修改ColorSyntaxVisitor.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Tokenizer.TokenInterface;

using System.Windows.Controls;

using System.Windows.Media;

using System.Windows.Documents;

 

namespace Tokenizer

{

    sealed class ColorSyntaxVisitor : ITokenVisitor

    {

        private readonly RichTextBox target;

 

        public ColorSyntaxVisitor(RichTextBox rtb)

        {

            this.target = rtb;

            this.target.Document.Blocks.Clear();

        }

 

        private void Write(string token, SolidColorBrush color)

        {

            target.AppendText(token);

            int offsetToStartOfToken = -1 * token.Length - 2;

            int offsetToEndOfToken = -2;

            TextPointer start =

                target.Document.ContentEnd.GetPositionAtOffset(offsetToStartOfToken);

            TextPointer end =

                target.Document.ContentEnd.GetPositionAtOffset(offsetToEndOfToken);

            TextRange text = new TextRange(start, end);

            text.ApplyPropertyValue(TextElement.ForegroundProperty, color);

        }

 

        #region ITokenVisitor Members

        void ITokenVisitor.VisitComment(string token)

        {

            Write(token, Brushes.Black);

        }

 

        void ITokenVisitor.VisitIdentifier(string token)

        {

            Write(token, Brushes.Black);

        }

 

        void ITokenVisitor.VisitKeyword(string token)

        {

            Write(token, Brushes.Blue);

        }

 

        void ITokenVisitor.VisitOperator(string token)

        {

            Write(token, Brushes.Black);

        }

 

        void ITokenVisitor.VisitPunctuator(string token)

        {

            Write(token, Brushes.Black);

        }

 

        void ITokenVisitor.VisitStringLiteral(string token)

        {

            Write(token, Brushes.Green);

        }

 

        void ITokenVisitor.VisitWhitespace(string token)

        {

            Write(token, Brushes.Black);

        }

        #endregion

    }

}

(16) 修改SourceFile.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Tokenizer.TokenInterface;

using Tokenizer.TokenClass;

 

namespace Tokenizer

{

    class SourceFile : IVisitable

    {

        private IVisitableToken[] tokens =

              {

                     new KeywordToken("using"),

                     new WhitespaceToken(" "),

                     new IdentifierToken("System"),

                     new PunctuatorToken(";"),

                     new WhitespaceToken("/n"),

                     new WhitespaceToken("/n"),

                     new KeywordToken("class"),

                     new WhitespaceToken(" "),

                     new IdentifierToken("Greeting"),

                     new WhitespaceToken("/n"),

                     new PunctuatorToken("{"),

                     new WhitespaceToken("/n"),

                     new WhitespaceToken("    "),

                     new KeywordToken("static"),

                     new WhitespaceToken(" "),

                     new KeywordToken("void"),

                     new WhitespaceToken(" "),

                     new IdentifierToken("Main"),

                     new PunctuatorToken("("),

                     new PunctuatorToken(")"),

                     new WhitespaceToken("/n"),

                     new WhitespaceToken("    "),

                     new PunctuatorToken("{"),

                     new WhitespaceToken("/n"),

                     new WhitespaceToken("        "),

                     new IdentifierToken("Console"),

                     new OperatorToken("."),

                     new IdentifierToken("WriteLine"),

                     new PunctuatorToken("("),

                     new StringLiteralToken("/"Hello, world/""),

                     new PunctuatorToken(")"),

                     new PunctuatorToken(";"),

                     new WhitespaceToken("/n"),

                     new WhitespaceToken("    "),

                     new PunctuatorToken("}"),

                     new WhitespaceToken("/n"),

                     new PunctuatorToken("}"),

              };

 

        public void Accept(ITokenVisitor visitor)

        {

            foreach (IVisitableToken token in tokens)

            {

                token.Accept(visitor);

            }

        }

    }

}

(17) 修改MainWindow.xaml.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

 

namespace Tokenizer

{

    /// <summary>

    /// Interaction logic for MainWindow.xaml

    /// </summary>

    public partial class MainWindow : Window

    {

        public MainWindow()

        {

            InitializeComponent();

        }

 

        private void buttonOpen_Click(object sender, RoutedEventArgs e)

        {

            SourceFile source = new SourceFile();

            ColorSyntaxVisitor visitor = new ColorSyntaxVisitor(richTextBoxCodeText);

            source.Accept(visitor);

        }

    }

}

(18) 运行测试

 

资源下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值