青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-341  評論-2670  文章-0  trackbacks-0

    詞法分析器生成器終于做好了,因此我又畫了一個狀態機然后生成了一個詞法分析器,因此開始研究IDE的智能提示的技術了。智能提示的技術有幾個要點,第一個是無論怎么慢都不能妨礙你打字,第二個是崩潰了也不能讓IDE關掉,要重啟分析器。因此我做了一個小實驗。首先我將NativeX語言的著色器跟詞法分析器都做好了,因此我要做的事情就是在你打字的時候,用另外一個線程進行詞法分析,得到結果之后用一個框框來展示出光標所在的那個token:




    注意光標所在的位置是在方框的內部。為了實現這個過程,首先我們要一個安全的多線程機制。我們把詞法分析作為一個請求來看,在打字的過程中我們就不斷把請求發送到詞法分析器頭上,然后詞法分析器分析完了就會發個消息給窗口然后傳送結果。我們注意到如果打字太快導致來不及處理的話,可能會積累若干個請求,不過那些請求實際上只有最后一個需要被處理,之前的那些來不及處理的舊請求都會被忽略。反正我們的字已經打完了,詞法分析器就不需要分析那些我們還沒打完的字了。因此我們把它抽象一下:

    我們有一個請求的類,這個類需要的數據有輸入類型、輸出類型、計算方法以及傳送方法。為什么要傳送方法呢?因為計算是在另外一個線程完成的,因此在調用傳送方法的時候也是在另外一個線程完成的,所以我們得提供一個函數來接受分析后的結果,然后用一種安全的方法傳送到我們想要的地方去。因此我們就把這個過程分成了兩個類,一個處理多線程的問題的抽象類,和一個用來提供計算方法和傳送方法的子類:
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading;
 6 
 7 namespace CodeBoxControl
 8 {
 9     public abstract class CalculationNotifier<I, O> : IDisposable
10     {
11         private Thread workingThread = null;
12         private I analyzingInput = default(I);
13         private bool analyzingInputAvailable = false;
14         private Semaphore codeSemaphore = null;
15         private object locker = null;
16 
17         public CalculationNotifier()
18         {
19             this.locker = new object();
20             this.codeSemaphore = new Semaphore(01);
21             this.workingThread = new Thread(Run);
22             this.workingThread.Start();
23         }
24 
25         public void Analyze(I input)
26         {
27             bool needRelease = false;
28             lock (this.locker)
29             {
30                 if (!this.analyzingInputAvailable)
31                 {
32                     needRelease = true;
33                 }
34                 this.analyzingInputAvailable = true;
35                 this.analyzingInput = input;
36             }
37             if (needRelease)
38             {
39                 this.codeSemaphore.Release(1);
40             }
41         }
42 
43         public void Dispose()
44         {
45             this.workingThread.Abort();
46             this.codeSemaphore.Dispose();
47         }
48 
49         protected abstract O Calculate(I input);
50         protected abstract void Receive(O output);
51 
52         private void Run()
53         {
54             while (true)
55             {
56                 this.codeSemaphore.WaitOne();
57                 I input = default(I);
58                 lock (this.locker)
59                 {
60                     input = this.analyzingInput;
61                     this.analyzingInputAvailable = false;
62                 }
63                 O output = Calculate(input);
64                 Receive(output);
65             }
66         }
67     }
68 }
69 

    怎么使用它呢?我們只需要不斷地把數據發送給Analyze函數,那個函數就會自動替我們處理好跟同步相關的所有問題了,然后在另外一個線程調用分析函數和返回結果:
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using CodeBoxControl;
 6 using CodeBoxControl.CodeProvider;
 7 
 8 namespace CodeForm
 9 {
10     class NativeXAnalyzingResult
11     {
12         public List<CodeToken> Tokens { getset; }
13     }
14 
15     interface INativeXAnalyzingResultReceiver
16     {
17         void Receive(NativeXAnalyzingResult result);
18     }
19 
20     class NativeXCodeAnalyzer : CalculationNotifier<string, NativeXAnalyzingResult>
21     {
22         private NativeXTokenizer tokenizer = new NativeXTokenizer();
23         private INativeXAnalyzingResultReceiver receiver = null;
24 
25         public NativeXCodeAnalyzer(INativeXAnalyzingResultReceiver receiver)
26         {
27             this.receiver = receiver;
28         }
29 
30         protected override NativeXAnalyzingResult Calculate(string input)
31         {
32             NativeXAnalyzingResult result = new NativeXAnalyzingResult();
33             result.Tokens = this.tokenizer.Tokenize(input.ToCharArray());
34             return result;
35         }
36 
37         protected override void Receive(NativeXAnalyzingResult output)
38         {
39             this.receiver.Receive(output);
40         }
41     }
42 }
43 

    這個類就是用來負責做詞法分析的了。當然我們注意到此時接受數據的過程還是被抽象掉了,因為這個過程實際上應該讓插件去處理,因為插件才知道要怎么畫框。目前的控件支持兩個插件,一個是著色器,另一個是監視器。監視器負責監聽字符串的改變和插手繪圖的過程,我們可以看出這個插件是如何把詞法分析結果和畫框框聯系在一起的:
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using CodeBoxControl;
  6 using System.Windows.Forms;
  7 using CodeBoxControl.Core;
  8 using CodeBoxControl.CodeProvider;
  9 using System.Drawing;
 10 
 11 namespace CodeForm
 12 {
 13     class NativeXControlPanel
 14         : ITextEditorControlPanel
 15         , INativeXAnalyzingResultReceiver
 16         , IDisposable
 17     {
 18         private ITextEditorControlPanelCallBack callback = null;
 19         private NativeXAnalyzingResult analyzingResult = null;
 20         private NativeXCodeAnalyzer analyzer = null;
 21 
 22         private TextPosition grayStart = new TextPosition(00);
 23         private TextPosition grayEnd = new TextPosition(00);
 24 
 25         public int Width
 26         {
 27             get
 28             {
 29                 return 0;
 30             }
 31         }
 32 
 33         public void InstallCallBack(ITextEditorControlPanelCallBack callback)
 34         {
 35             this.analyzer = new NativeXCodeAnalyzer(this);
 36             this.callback = callback;
 37             this.callback.TextEditorBox.SelectionChanged += new EventHandler(TextEditorBox_SelectionChanged);
 38         }
 39 
 40         public void OnEdit(CodeBoxControl.Core.TextPosition start, CodeBoxControl.Core.TextPosition oldEnd, CodeBoxControl.Core.TextPosition newEnd)
 41         {
 42             this.analyzer.Analyze(this.callback.TextEditorBox.Text);
 43         }
 44 
 45         public bool NeedColorLineForDisplay(int lineIndex)
 46         {
 47             return this.grayStart != this.grayEnd && this.grayStart.row <= lineIndex && lineIndex <= this.grayEnd.row;
 48         }
 49 
 50         public void ColorLineForDisplay(int lineIndex, int[] colors)
 51         {
 52             TextLine<TextEditorBox.LineInfo> line = this.callback.TextEditorBox.TextProvider[lineIndex];
 53             int length = line.CharCount;
 54 
 55             int start = grayStart.row == lineIndex ? Math.Min(grayStart.col, length) : 0;
 56             int end = grayEnd.row == lineIndex ? Math.Min(grayEnd.col, length) : line.CharCount;
 57             for (int i = start; i < end; i++)
 58             {
 59                 colors[i] = NativeXColorizer.BlockPointColorId;
 60             }
 61         }
 62 
 63         public void DrawLineBackground(Graphics g, int lineIndex, Rectangle backgroundArea)
 64         {
 65         }
 66 
 67         public void DrawLineForeground(Graphics g, int lineIndex, Rectangle backgroundArea)
 68         {
 69             if (NeedColorLineForDisplay(lineIndex))
 70             {
 71                 TextLine<TextEditorBox.LineInfo> line = this.callback.TextEditorBox.TextProvider[lineIndex];
 72                 int length = line.CharCount;
 73                 int start = grayStart.row == lineIndex ? Math.Min(grayStart.col, length) : 0;
 74                 int end = grayEnd.row == lineIndex ? Math.Min(grayEnd.col, length) : line.CharCount;
 75 
 76                 int x1 = this.callback.TextEditorBox.TextPositionToViewPoint(new TextPosition(lineIndex, start)).X;
 77                 int x2 = this.callback.TextEditorBox.TextPositionToViewPoint(new TextPosition(lineIndex, end)).X;
 78                 g.DrawRectangle(Pens.Gray, x1, backgroundArea.Top, x2 - x1, backgroundArea.Height);
 79             }
 80         }
 81 
 82         public void DrawControlPanel(Graphics g, int lineIndex, Rectangle controlPanelArea)
 83         {
 84         }
 85 
 86         public void DrawControlPanelBackground(Graphics g, Rectangle backgroundArea)
 87         {
 88         }
 89 
 90         public void OnMouseDown(int lineIndex, Rectangle controlPanelArea, Point relativePosition, System.Windows.Forms.MouseButtons buttons)
 91         {
 92         }
 93 
 94         public void OnMouseMove(int lineIndex, Rectangle controlPanelArea, Point relativePosition, System.Windows.Forms.MouseButtons buttons)
 95         {
 96         }
 97 
 98         public void OnMouseUp(int lineIndex, Rectangle controlPanelArea, Point relativePosition, System.Windows.Forms.MouseButtons buttons)
 99         {
100         }
101 
102         public void Receive(NativeXAnalyzingResult result)
103         {
104             this.callback.TextEditorBox.Invoke(new MethodInvoker(() =>
105             {
106                 this.analyzingResult = result;
107                 UpdateBlock();
108             }));
109         }
110 
111         public void Dispose()
112         {
113             this.analyzer.Dispose();
114         }
115 
116         private void UpdateBlock()
117         {
118             NativeXAnalyzingResult result = this.analyzingResult;
119             TextPosition pos = this.callback.TextEditorBox.SelectionCaret;
120             if (result != null)
121             {
122                 foreach (CodeToken token in result.Tokens)
123                 {
124                     if (token.Start < pos && pos < token.End)
125                     {
126                         this.grayStart = token.Start;
127                         this.grayEnd = token.End;
128                         return;
129                     }
130                 }
131                 this.grayStart = new TextPosition(00);
132                 this.grayEnd = new TextPosition(00);
133             }
134         }
135 
136         private void TextEditorBox_SelectionChanged(object sender, EventArgs e)
137         {
138             UpdateBlock();
139         }
140     }
141 }
142 


    這里我們借助了System.Windows.Forms.Control.Invoke來將一整個閉包壓到了消息循環里面,然后消息循環來執行這個閉包,因此接收數據的過程就在UI線程上完成了。Invoke跟SendMessage其實是差不多的。我們還能看出這個插件的接口叫ControlPanel,所以是用來干預一切變化的。這里有Width屬性但是設置成0了,如果不是0的話就可以模仿VisualStudio左邊那個放斷點的控制欄了,這個在之前已經演示過了。

    到這里如何在非UI線程處理代碼的技術就介紹完了,現在讓我們來看著色器和詞法分析器的樣子哈。首先上著色器的狀態機:


    然后是詞法分析器的狀態機:


    至于他們生成的代碼,可以去Vczh Library++ 3.0這里看哈。

 

posted on 2010-10-14 08:23 陳梓瀚(vczh) 閱讀(5879) 評論(6)  編輯 收藏 引用 所屬分類: 開發自己的IDE

評論:
# re: 開發自己的IDE(六)[未登錄] 2010-10-14 08:33 | Lyt
看一次流一次口水…  回復  更多評論
  
# re: 開發自己的IDE(六) 2010-10-14 16:51 | Pear
MB真帥氣。。MB真帥氣。。真帥氣。。  回復  更多評論
  
# re: 開發自己的IDE(六) 2010-10-16 07:57 | mm
好強大!!!  回復  更多評論
  
# re: 開發自己的IDE(六) 2010-10-17 08:45 | hhh2000
圖有點小,有些符號看不清楚……

對著色器狀態機的圖有點疑問:1、如果CharIn是指單個字符的話,好像少了一個狀態。2、StringIn指向自己的邊是非 \ 和 " 號嗎(圖看不清)?這好像不大對吧。還

有單雙引號一般只影響本行,加上一個行尾的狀態約束一下,這樣在引號不匹配的情況下看起來會好一些。
  回復  更多評論
  
# re: 開發自己的IDE(六) 2010-10-19 01:41 | 陳梓瀚(vczh)
@hhh2000
為了簡單,char我還是允許他擁有多個字符了,反正對于一個字符的狀態可以正確解析,而且這是用在IDE上面的,勢必跟編譯器會有一些小的區別

StringIn那個東西是\.哈,也就是任意字符的意思。  回復  更多評論
  
# re: 開發自己的IDE(六) 2010-10-19 01:42 | 陳梓瀚(vczh)
@hhh2000
到了行末尾其實就是一個\n字符,只要你在狀態機上面把\n給排除了,自然就會只有一行了。  回復  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美视频在线观看视频极品| 一区二区久久| 玖玖玖国产精品| 精品不卡一区| 欧美激情国产精品| 欧美高清hd18日本| 亚洲婷婷综合久久一本伊一区| 日韩午夜中文字幕| 国产精品手机视频| 欧美日本韩国在线| 亚洲午夜影视影院在线观看| 亚洲在线中文字幕| 黄色日韩在线| 亚洲精品一区在线观看| 国产精品久久久久久久久免费 | 欧美在线高清| 亚洲黄色一区| 亚洲素人一区二区| 永久域名在线精品| 一本色道久久综合亚洲精品婷婷| 国产欧美一区二区精品秋霞影院 | 午夜在线观看欧美| 久久久亚洲高清| 亚洲一品av免费观看| 欧美一区二区黄| 99国产精品久久久久久久| 中文久久乱码一区二区| 亚洲高清色综合| 亚洲一区二区三区免费在线观看| 激情婷婷欧美| 亚洲一区二区三区中文字幕在线 | 亚洲黄色成人久久久| 一区二区三区日韩精品| 亚洲二区精品| 香蕉视频成人在线观看 | 国产区在线观看成人精品| 欧美激情在线免费观看| 国产午夜精品在线| 夜夜嗨av色一区二区不卡| 一区二区亚洲| 性欧美精品高清| 亚洲视频一区二区在线观看| 美女黄毛**国产精品啪啪| 性色av香蕉一区二区| 欧美日本免费| 亚洲日本中文字幕区| 国产亚洲精品bt天堂精选| 一本一本大道香蕉久在线精品| 尤物精品国产第一福利三区 | 亚洲综合二区| 亚洲自拍偷拍色片视频| 欧美久久一区| 最新国产成人在线观看| 在线观看三级视频欧美| 欧美在线日韩精品| 久久精品国产999大香线蕉| 欧美调教vk| 99精品国产福利在线观看免费| 亚洲激情在线视频| 美女脱光内衣内裤视频久久网站| 久久久噜久噜久久综合| 国产亚洲欧洲| 欧美一二三视频| 欧美一进一出视频| 国产啪精品视频| 欧美一区日韩一区| 久久欧美肥婆一二区| 国产一区自拍视频| 亚洲一区二区三区精品在线观看| 欧美国产欧美亚洲国产日韩mv天天看完整 | 日韩一二三区视频| 欧美精品在线视频观看| 亚洲韩国日本中文字幕| 日韩一级大片| 国产精品久久| 午夜精品久久久久久久白皮肤| 久久精品毛片| 在线观看日韩av先锋影音电影院| 免费在线成人av| 亚洲人成久久| 亚洲欧美激情视频| 国产一区二区三区四区三区四| 久久久91精品国产一区二区三区| 浪潮色综合久久天堂| 亚洲欧洲视频| 国产精品进线69影院| 欧美影院成人| 亚洲国产精品va在看黑人| 在线亚洲欧美视频| 国产九色精品成人porny| 久久精品动漫| 亚洲精品一区二| 久久精品理论片| 日韩午夜精品视频| 国产农村妇女精品一区二区| 久久久一区二区| 亚洲国产精品悠悠久久琪琪| 亚洲欧美久久久久一区二区三区| 国产在线视频欧美一区二区三区| 欧美大片在线看| 亚洲欧美在线x视频| 亚洲电影中文字幕| 午夜精品免费视频| 亚洲欧洲一区二区在线观看| 国产精品v欧美精品v日本精品动漫| 欧美伊久线香蕉线新在线| 亚洲欧洲综合另类| 久久九九精品| 一区二区三区黄色| 精品999成人| 国产日韩欧美一二三区| 欧美精品v日韩精品v国产精品| 亚洲综合久久久久| 亚洲国产专区| 免费成人高清视频| 欧美一二三区精品| 中文日韩电影网站| 亚洲国产精品第一区二区三区| 国产精品日本| 欧美日韩视频专区在线播放| 久久―日本道色综合久久| 亚洲免费影视第一页| 亚洲日本中文字幕| 欧美激情在线观看| 欧美电影在线播放| 久久久精品国产免大香伊| 亚洲欧美制服另类日韩| 99亚洲精品| 99国产精品视频免费观看| 亚洲国产另类久久精品| 国内一区二区三区在线视频| 国产精品美女久久久免费| 欧美日韩另类在线| 欧美激情精品久久久| 久久综合给合久久狠狠狠97色69| 欧美影院一区| 欧美一区中文字幕| 久久精品国产精品亚洲精品| 亚洲欧美中文日韩v在线观看| 亚洲无限乱码一二三四麻| 99re热这里只有精品视频| 韩国视频理论视频久久| 国产日韩欧美一区在线| 国产伦精品一区二区| 国产精品视频你懂的| 国产精品亚洲激情| 国产丝袜一区二区| 国产伪娘ts一区 | 久久这里只精品最新地址| 久久精品视频免费播放| 久久亚洲二区| 欧美国产综合| 欧美日韩一区二区三区在线视频 | 国产精品日韩高清| 国产精品日韩在线观看| 国产日本亚洲高清| 一区二区视频在线观看| 最新中文字幕一区二区三区| 日韩视频在线一区二区| 亚洲婷婷综合色高清在线| 亚洲欧美在线播放| 久久久久久**毛片大全| 欧美www在线| 亚洲精品字幕| 亚洲欧美日韩精品久久亚洲区| 欧美一区午夜视频在线观看| 奶水喷射视频一区| 欧美亚州韩日在线看免费版国语版| 国产精品福利在线| 精品999网站| 一区二区欧美在线| 久久精品国产99国产精品| 欧美大片在线观看一区二区| 亚洲精品欧美日韩| 久久av最新网址| 欧美日本国产视频| 国语精品一区| 亚洲视频一区在线| 免费日韩视频| 亚洲尤物视频在线| 欧美aa国产视频| 国产色产综合色产在线视频| 91久久久一线二线三线品牌| 亚洲欧美日韩国产一区| 欧美国产精品| 亚洲欧美一级二级三级| 欧美jizzhd精品欧美巨大免费| 国产精品人人爽人人做我的可爱| 亚洲精品国产精品国产自| 欧美在线综合| 亚洲免费观看高清完整版在线观看熊| 欧美一级视频精品观看| 欧美另类在线观看| 激情视频亚洲| 欧美一区国产一区| 99国产精品自拍| 欧美久久久久久蜜桃| 亚洲电影中文字幕| 久久狠狠一本精品综合网| 99精品黄色片免费大全|