• <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>

            升C小調狂想曲

            <遞歸的憂傷>
            posts - 10, comments - 71, trackbacks - 0, articles - 0
               :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            2009年6月3日

            JustType新命令translate~ 實時翻譯! 廢話不多說,截2個圖先:(http://justtype.cloudapp.net 我前一篇博文有更詳細地介紹這個JustType項目)

            image

            image

             

            我們經常會有這種需求,就是翻譯一小段看不太懂的外語。Google提供了翻譯服務,但是如果每次都要打開Google那個翻譯頁面,倒也挺麻煩。于是我把翻譯功能也做成了JustType的命令,現在在JustType中就可以通過translate命令來翻譯任何語言的文字了。想體驗的話:http://justtype.cloudapp.net

             

            整個translate命令的腳本代碼很簡單,先用正則表達式分析了命令結構,然后向網頁寫入javascript代碼,在javascript中引用google函數庫,調用對應函數即可:

            import System
            import System.Text
            import System.Text.RegularExpressions
            import System.Web

            from System.Text.RegularExpressions import *

            def OnCommand(command):
                sourceLang = "en"
                targetLang = "zh"
                text = command
                chkAdvancedUsage = Regex("(?<text>(.|\n)+?)\\s+from (?<from>[a-zA-Z]+) to (?<to>[a-zA-Z]+)")
                m = chkAdvancedUsage.Match(command)
                if m.Success:
                    sourceLang = m.Groups["from"].Value
                    targetLang = m.Groups["to"].Value
                    text = m.Groups["text"].Value
                render = "<div id=\"divTranslation\" style=\"background-color:#f0f8ff; border:dotted 1px gray; padding:5px; width:500px; \"></div>\n"
                render += "<script type=\"text/javascript\" src=\"http://www.google.com/jsapi\"></script>\n"
                render += "<script type=\"text/javascript\">\n"
                render += "google.load(\"language\", \"1\");\n"
                render += "function initializeTranslation() { google.language.translate(\"" + System.Web.HttpUtility.HtmlEncode(text.Replace("\n", " ").Replace("\r", "")) + "\",\"" + sourceLang + "\", \"" + targetLang + "\", function(result) {\n"
                render += "if (!result.error) { document.getElementById(\"divTranslation\").innerHTML = result.translation; } else { document.getElementById(\"divTranslation\").innerHTML = \"error!\" }\n"
                render += "}); }"
                render += "google.setOnLoadCallback(initializeTranslation);"
                render += "</script>"
                SetTipText(render)
                return True

             

            在JustType中,一個命令對應一個執行腳本,我們可以自己寫新腳本,同時可以允許其他人調用自己寫的程序。大家互相分享自己智慧的同時,也在利用編程技術增加自己和他人的工作效率。更多的信息請到http://justtype.cloudapp.net 獲取。 :)

            posted @ 2009-06-03 21:00 陳坤 閱讀(7412) | 評論 (5)編輯 收藏

            2009年6月2日

            每當我們打開電腦,我們可能經常會做一些習慣性的動作。例如查一下郵件啦,看看新聞啦,觀察一下股票走向啦。仔細想一下就發現,這里面有很多動作是我們每天都會重復的。有沒有可能更方便一點呢?

            有。很簡單,身為程序員的我們,為每種固定的操作寫個小程序就好了。但這樣一來會帶來幾個問題:

            1. 小程序寫多了,很難統一管理。而且有些帶參數的程序(例如按照一定股票編號去查詢價格的程序),使用起來并不一定方便。

            2. 我們可能經常使用不同的電腦,那么要同步這些小程序會非常頭疼。

            3. 你也寫,我也寫,大家寫了大量重復的小程序,很浪費資源。

            為了應對這些問題,我提出了一個叫JustType的框架,我們可以在http://justtype.cloudapp.net 訪問它。

            JustType的界面就是一個文本框,一切都在這個文本框中進行。在JustType框架中,每個小程序都對應一個命令,命令可帶參數。寫好的小程序會保存在服務器,每一個人都可以選擇是否要公開自己的小程序。這樣大家可以很方便地共享自己的成果。

            讓我們來逐一看看JustType擁有的功能。

            首先,最基本的,你可以在JustType中輸入一個網址,一按回車就會訪問該網址。

            image

            當然,僅僅是這樣的話,很傻。因為瀏覽器的地址欄更好用多了。但是,JustType遠遠不止這點。

            我們可以為一個命令設置一個別名,例如:

            image

            經過這樣的設置后,下次我只要打cppblog就會自動進入http://www.shnenglu.com 了。

            還有很多時候,我們會遇到一些小小的計算問題。Windows那個計算器實在很不好用,讓我們看看JustType:

            image

            image

            這個calc命令會將后面的表達式求值并顯示出來。實際上,這里這個表達式是Python的表達式,JustType中所有的小程序都運行在IronPython上,并且可以使用.net framework類庫中的大多數功能。

            當然,除了簡單的表達式以外,我們還可以執行更復雜的腳本:

            image

            輸入這個命令之后,界面就會變成下面的樣子:

            image

            MultiLineTextMode是一個預定義函數,功能是將主界面上的文本框變成多行模式,這樣我們就可以輸入更復雜的腳本了。下面我們試試使用一些.net framework中的功能:

            image

            輸出結果如下:

            image

            SetTextBoxText也是一個預定義函數,可以改變主界面中文本框內的文本。更多的預定義函數描述可以在http://justtype.cloudapp.net/Help.aspx 中看到。

            除了臨時執行腳本以外,我們也可以將腳本寫成小程序保存起來。輸入newcommand命令,就會進入創建命令的頁面。我們將這個小程序命名為translate,然后輸入以下代碼:

            import System
            import System.Web

            def OnCommand(command):
                GoToURL("http://dict.youdao.com/search?q=" + System.Web.HttpUtility.UrlEncode(command))
                return True

            程序依然是用IronPython寫,其實Python語法很簡單。http://www.python.org 感興趣的用戶可以去看看。這個OnCommand函數就是用來接收消息的。當JustType收到命令后,會找到這個命令對應的腳本,并將參數傳給腳本的OnCommand函數來執行。我們看到,這里程序調用了GoToURL函數,轉向了有道詞典的頁面。在創建了這個程序后,我們就可以在JustType的文本框中輸入下面的命令:

            image

            一按回車,就會轉向翻譯結果:

            image

            類似地,我們可以寫出很多很多方便實用的小程序。在我們創建程序時,我們可以選擇是否要公開。如果公開的話,別的用戶就可以通過“你的用戶名.程序名”來調用你的程序。例如我的用戶名是ck,那么其他用戶就可以輸入ck.translate來調用我的程序,當然他喜歡的話也可以用setalias來設置一個方便的別名。如果所有公開的程序中,只有我這個程序叫做translate,那么其他用戶不打ck.translate而直接打translate也可以成功調用。

            另外,JustType提供一種簡單的數據存儲。每一個程序在一個用戶的賬戶中會有一個獨立的存儲空間,可以存儲1000行數據。例如我利用這個特性開發了一個叫做note的小程序,可以臨時記錄一些小筆記:

            image

            那么之后我就可以看到我的筆記:

            image

            所有的程序和數據,都存放在服務器端,用戶不用擔心不同機器的問題。無論你走到哪里,都可以像在一臺機器上一樣訪問所有服務和數據。

            新服務剛剛搭建好,歡迎大家試用和提供意見喔。網址是http://justtype.cloudapp.net

            posted @ 2009-06-02 16:27 陳坤 閱讀(2005) | 評論 (9)編輯 收藏

            2008年10月9日

            未讀過本系列文章的,請先參考http://www.shnenglu.com/ckyap/archive/2008/10/06/63287.html

            BoxSharp 最新進展!

            image

            輸入硬盤地址時的自動提示,另外還有按TAB鍵即可切換目錄,行為與cmd命令行里面輸入地址欄時類似

            image 

            Note功能,可以隨時記下一下小事情。命令為/note something。輸入/note會打開當前所有notes列表。

            工具欄自定義按鈕功能,輸入/toolbutton add "button name" command即可自定義一個按鈕,按下即會執行指定的command命令,效果與在文本框中輸入command然后按回車一樣。

            之前一位朋友提到的/define功能,我覺得如果需要參數,就應該寫成新插件,而不是定義成另外一個命令;如果不需要參數,那就可以通過現在這個toolbutton實現。所以暫時不做了。

            全局熱鍵在WPF下面貌似很有問題。。。至少我還沒找到解決方案,這幾天太忙了,有空我還要繼續想辦法。

            最新版這里下載 http://code.google.com/p/boxsharp/downloads/list

            posted @ 2008-10-09 22:29 陳坤 閱讀(1461) | 評論 (11)編輯 收藏

            2008年10月6日

            這篇文章是繼續上一篇《命令的繽紛》來闡述的。未閱讀過前一篇的請參見這里:http://www.shnenglu.com/ckyap/archive/2008/09/12/61641.html

            功能可以看下面幾個圖:

             

            image

            總而言之,BoxSharp提供一種可擴展的方式讓你在一個TextBox中干任何事情。

            此項目已經正式作為開源項目放在Google Code上啦!大家可以在這里訪問項目主頁:http://boxsharp.googlecode.com/

            那啥Subversion搞了我一個小時。。。真是感嘆現在的高科技啊。

            在這里可以下載最新的可執行文件,只能運行在Win32平臺上,需要.net framework 3.5支持:

            http://code.google.com/p/boxsharp/downloads/list

            在這里可以查看最新的文檔:

            http://code.google.com/p/boxsharp/w/list

            在這里可以查看源代碼:(要有Subversion才能下載到代碼)

            http://code.google.com/p/boxsharp/source/checkout

            posted @ 2008-10-06 00:13 陳坤 閱讀(2085) | 評論 (11)編輯 收藏

            2008年9月12日

            這篇文章是繼續上一篇《命令的癡狂》來闡述的。未閱讀過前一篇的請參見這里:http://www.shnenglu.com/ckyap/archive/2008/09/09/61427.html

            這一次我做了一個可以自定RSS源的新聞滾動播放器插件,滾動新聞就放在TextBox的旁邊,鼠標放過去有新聞簡介,點擊就可以打開瀏覽器瀏覽新聞。這樣在工作之余,抬起頭就能看看當時最新的新聞,不亦樂乎!

            image 

             

            除了新聞播放器,這兩天主要做的就是一個智能提示框。就像Firefox那個“棒極了的地址欄”一樣,我希望這個框框能智能的提示我一些操作和命令。大多數時候,我們想通過一些熟悉的名字來啟動一些程序,比如輸入QQ,就給我啟動QQ,輸入IE,就給我打開IE。有時候我們也希望通過一些簡稱來訪問一些網站,比如輸入baidu,就給我打開百度,輸入google就給我打開google,而不需要輸入完整的http://www.baidu.com 。當然,如果讓我們手動添加所有的命令,比如我親自告訴程序,“如果我輸入baidu就給我打開http://www.baidu.com”,這當然很輕松,但是我很懶,我不想每次都親自添加這種命令,我需要他自動幫我找出來。

            第一個我能想到的地方,就是開始菜單的“程序”目錄里了。遍歷里面所有的快捷方式,把名字分析一下,加入待選列表,搞定。不過這個名字分析的過程比較麻煩,因為比如QQ他的快捷方式默認是叫“騰訊QQ2009”,但是我只想輸入QQ就打開它。另外比如Microsoft Visual Studio 2008,我只想輸入MVS這個簡稱來訪問它。這個就是一些特征的提取了,也不會太難。

            image

            image

            除了程序目錄,Program Files也是一個好地方,里面的exe一般都是有用的程序,提取出來,一起放進來,它就能提示我更多東西了。

            第二個主要地方,就是收藏夾和瀏覽器歷史了。遍歷里面所有的項目,分析一下,也加入待選列表。同樣是分析過程比較重要,決定了能否得到正確的提示。

            image

            image

            選到需要的項目上,按回車就行了。這里我準備對使用次數做排名,使用得多的項目會浮到最上面去,也就是直接按回車就會啟動的位置。

             

            OK,現在這個框框可以干的所有事情,總結一下:

            1.可以輸入/exit,退出。(別扔磚頭。。。)

            2.可以輸入/baidu,/google等搜索引擎對一個詞進行搜索。搜索引擎可以通過配置文件指定。

            3.可以輸入一個完整的路徑名,或者一個完整的URL,打開訪問。

            4.可以輸入C#代碼,立即執行。(可以進行表達式運算等操作)可以保存代碼段,以后通過一個名字來直接執行它。

            5.可以隨時看到最新的新聞滾動播放,點擊即可在瀏覽器中打開。RSS新聞來源可以自定。

            6.自動索引常用程序和網頁,可以通過輸入它們的簡稱,或任何你想得到的代表詞語來運行它們。

             

            下一步準備做的,桌面搜索~

            posted @ 2008-09-12 00:29 陳坤 閱讀(1526) | 評論 (6)編輯 收藏

            2008年9月9日

            朋友,可曾想過把所有的事情都放到一個TextBox里面去做?今天我就做了一個,理論上可以干任何事情的TextBox。嘿嘿。

            實習的日子實在是挺忙,CNScript還停留在語法分析的階段,一直沒時間去打開那個大工程(其實是有時間的,可惜零碎的時間都被我拿來寫這篇文章要講的這些小東西了)。

            我們在瀏覽網頁時,或許會突然想打開某個程序,比如計算器,算點東西;又可能想打開Photoshop,處理一下網頁上的某個圖片;又可能想打開記事本,摘抄一些文字。這時我們不得不回到桌面,或者打開那個碩大的開始菜單,在程序里面去找我們想要的東西。

            有的時候,我們還會重復做一些機械的動作,比如讀一個文件,檢查是否有變動,比如檢查某個文件夾,看是否有新文件。當然,你可以寫一個程序來完成這個操作,但是有時候這種操作你覺得最多就重復個兩三次,你不會愿意去打開Visual Studio創建一個工程。

            歸結本質,我們就是想要一個隨叫隨到的,可以有一定能力幫我們做事情的東西。但是如果這個東西太大,會擋住我們正在瀏覽的網頁或者正在處理的文檔,那就不好了。所以我就想到了一個Topmost的TextBox,放在屏幕的頂端,也就是一般窗口的標題欄那里,這樣子不會擋住你要做的事情,而且在需要的時候 只要鼠標一移過去就可以用了。

            就是這樣一個TextBox

            OK,有了這樣一個TextBox,“隨叫隨到”已經完成了。但是我們需要這個TextBox有一定能力,比如我想運行一個程序,它能幫我運行,我想搜索一個詞語,他能幫我搜索,我想打開一個URL,他能幫我打開,我想計算一個表達式,他能幫我計算。但是人的需求是無限的,我們隨時會有新的需要,他不可能擁有所有的功能,那么如何讓他有能力做到任何事情呢?我們需要一種很強悍的可擴展性。玩過魔獸世界的朋友們一定知道,魔獸世界提供一個插件機制,玩家可以為游戲寫插件,來豐富游戲的功能,現在已經有千千萬萬的魔獸世界插件在各大網站上提供下載了,正是因為如此,魔獸世界才擁有著這么強的可擴展性。所以,我們這個TextBox也要用插件機制來驅動。在C#的Microsoft.CSharp名字空間中有一個C#的編譯器,可以將C#代碼編譯成托管組件,直接生成在內存中,以反射的方式來運行,這個機制為我們快速實現一個插件系統提供了可能。因此我選用了.net framework 3.5,用Windows Presentation Foundation來做界面,用C#來當我的腳本語言。

            俗話說,一不做,二不休,既然提供了插件,那我主程序除了運行插件以外就什么都不做了。運行了插件之后,將界面所有控件的控制權都交給插件,插件愛干啥就干啥去。主程序就是一個Window,Window上是一個StackPanel,Panel里面是一個TextBox,僅此而已。當然,插件可以向StackPanel里面加東西,以豐富這個條條的外觀內容。

             

            可執行程序的環境如下所示:(BoxSharp是這個程序的名字)

            image

            其中BoxSharpCore,BoxSharpRunPath,BoxSharpScripting,BoxSharpSearch是我剛寫好的幾個插件。

            BoxSharpCore插件提供了最基本的/exit命令,用于退出程序。此插件還控制了一些外觀方面的細節,包括自動記住TextBox上次退出時的位置,大小,用于下次啟動時恢復外觀。當輸入在文本框內的命令是一個正確命令時,會出現功能提示。

            image

            BoxSharpRunPath插件提供了打開文件夾,打開網址,運行命令的功能。

            image image image

            BoxSharpScripting插件提供了直接運行C#程序的功能。這個功能可以順便當作表達式計算器用,有時候有些運算(尤其是帶N個括號的復雜表達式)想立刻得出結果的,就不用打開計算器了。Print函數是用于將參數值直接寫在TextBox里面的。

            image

            image

            image

            也可以直接用/script命令打開一個窗口進行復雜的編程。

            image

            BoxSharpSearch插件是提供Web搜索功能的,我們可以通過配置文件來配置搜索引擎,插件啟動時會自動檢測配置項的。

            image

            image

            我有時間的話,完全可以寫更多的插件,比如自動檢測電子郵件,收發郵件,比如滾動播放新聞,比如自動搜新歌下載試聽,比如日歷,日程安排,約會提示,鬧鐘,這些都可以作為插件寫到里面去。而且,如果,我是說如果,如果很多用戶在用這個TextBox的話,他們可以共享他們自己寫的插件,將彼此的BoxSharp功能豐富。

            好吧,說到底了,.net framework 3.5能辦到的,這個TextBox就能辦到,但是你估計不會為了計算一個表達式而打開Visual Studio建工程的。這就是TextBox的魅力所在了,HOHO~

            posted @ 2008-09-09 22:58 陳坤 閱讀(2128) | 評論 (12)編輯 收藏

            2008年8月9日

                 摘要: 首先祝賀北京奧運會精彩開幕!!我親眼見到了鳥巢的壯觀景象,跟一堆外國人在一起看開幕式時我第一次感覺這么自豪!加油奧運,加油中國!今天把詞法分析器寫好了,一個巨大的switch。代碼如下://CNScriptLex.h  1 #ifndef CNSCRIPTLEX_H 2 #define CNSCRIPTLEX_H 3 ...  閱讀全文

            posted @ 2008-08-09 01:27 陳坤 閱讀(1967) | 評論 (8)編輯 收藏

            2008年8月8日

            上一篇我已經將各個詞法標記都設計好了,現在我們需要寫出一個程序,他讀入一個字符串,并輸出一系列Token,其中每個Token就是一個詞法標記,例如Keyword,Identifier,Number,Operator。

            假設我們輸入int a=100;這樣一個字符串作為代碼,那么我們將如何分析呢?

            首先讀入i,“i”符合Identifier的規則,但是繼續讀下去還有個n,一共是“in”,“in”也符合Identifier的規則,再讀,變成“int”,“int”符合Type的規則,繼續讀入后面的空格,變成“int ”,這個可不符合任何規則了,因此我們不能承認這一步,只好取上一步的可接受的結果Type:“int”。這樣我們就生成了第一個Token,他的類型是Type,值是“int”。以此類推,我們可以讀完整個程序,并完成整個詞法分析的過程。

            但是每一次都去判斷整個已讀入的字符串是否匹配某個規則,效率非常低,我們需要一種線性讀入字符串,并實時掌握目前字符串匹配狀況的辦法。確定性有窮自動機(DFA)就是這樣一種狀態機。

            下面是我為CNScript畫出的狀態圖:




            例如剛才讀的int a=100;
            我們一開始是在編號為0的狀態,現在輸入i,因為i屬于a-zA-Z的范圍,所以通過最后一幅圖我們看到,我們將邁向編號為44的狀態。再輸入n,因為n屬于a-zA-Z0-9_的范圍,所以我們繼續走在編號44的狀態,t也如此,但是輸入空格時,我們發現44號狀態沒有接受空格字符的出口,也就是無法繼續走下去了,而且44號狀態是一個可接受狀態,所以我們接受已經輸入了的“int”。
            在這里我們的44號狀態,接受意義是一個name,可以是Identifier,也可以是Keyword,也可以是Type,當我們取得name:“int”時,我們再判斷發現這是一個Type,所以我們得出Token:Type:“int”。然后狀態回到0號,繼續輸入剛才的空格。以此類推。

            所以我們只要按這個狀態圖去遍歷字符串,我們就會不斷的在各個狀態中輾轉反復,并不斷的得出Tokens。這就是我們詞法分析的基本原理。
            下一篇我會寫出這個DFA的代碼和具體使用方案。

            posted @ 2008-08-08 00:15 陳坤 閱讀(1536) | 評論 (3)編輯 收藏

            2008年8月5日

            要寫一個腳本引擎,首先要明確腳本長什么樣,具備哪些功能,需要有怎樣的能力。
            Since昨天我說第一版是面向過程,強類型,無閉包,無自定義結構,支持數組,那么我將腳本設計如下:

            CNScript 0.1 Draft

             

            Functionality:

            Procedure Oriented, No Custom Data Structures, No Closures, Strong Typed, Array Supported.

             

            Keywords:

            int,double,char,string,bool,void,if,else,for,do,while,return

             

            Statements:

            Single Expression:

            expression;

             

            Chunk:

            {

                     Statement1

                     Statement2

            }

             

            Array Declaration:

            type name[size];

             

            Variable Declaration:

            type name [= expression];

             

            Function definition:

            type FunctionName(type paramName1, type paramName2)

            Chunk

             

            IF-ELSE:

            if(expression)

            Statement1

            else

            Statement2

             

            FOR-LOOP:

            for(statement1 expression2;expression3)

            Statement

             

            WHILE-LOOP:

            while(expression)

            Statement

             

            DO-WHILE-LOOP:

            do

            Statement                                              

            while(expression);

             

            Expressions:

                     Values:

                               true

                               false

                               number

                               string

                               char

                               Variable Name

                               Array Name[index]

             

                     Assign:

                     name = expression

             

                     Function Call:

                     name(expression1,expression2)

             

                     Compares:

                               expression1 == expression2

                               expression1 != expression2

                               expression1 < expression2

                               expression1 > expression2

                               expression1 <= expression2

                               expression1 >= expression2

             

                     Boolean Operations:

                               !expression

                               expression1 && expression2

                               expression1 || expression2

             

                     Calculating:

                               expression++

                               expression

                               ++expression

                               --expression

                               expression1 + expression2

                               expression1expression2

                               expression1 * expression2

                               expression1 / expression2

                               expression1 % expression2

                               expression1 ^ expression2

                               (expression)

             

            Lexical Tokens:

            Spaces:

                     Space:                         (space_bar+)|(\n+) (\r+)|(\t+)

            TypeNames:

                     Type:                           (int)|(double)|(char)|(string)|(bool)|(void)

            Keywords:

                     Keyword_if:               if

                     Keyword_else:          else

                     Keyword_for:            for

                     Keyword_do:             do

                     Keyword_while:       while

                     Keyword_return:     return

            Brackets:

                     BigLeftBracket:        {

                     BigRightBracket:     }

                     MidLeftBracket:       [

                     MidRightBracket:    ]

                     SmallLeftBracket:    \(

                     SmallRightBracket: \)

            Identifier:

                     Identifier:                  (_+[a-zA-Z0-9_]+)|([a-zA-Z][a-zA-Z0-9_]*)

            Number Value:

                     Integer:                      0|[1-9][0-9]*

                     Double:                       (0|[1-9][0-9]*)\.[0-9]+

            Bool Value:

                     BoolValue:                 true|false

            Char:

                     CharValue:                 ‘(\\[^\r\n\t])|([^’\r\n\t])’

            String:

                     StringValue:               “((\\”)|[^\r\n])*”                                                                                       

            Operators:

                     Operator:                    =|\+|-|\*|/|%|^|(++)|(--)|(&&)|(\|\|)|(!)|<|>|(<=)|(>=)|(==)|(!=)

            Seprators:

                     Seprator:                    ;

             

            以上就是腳本設計初稿,如果后面發現有錯誤,會去更正的。

            按這個設計,寫出來的程序大概是下面這樣:

             1 int Foo(int value)
             2 {
             3    return value;
             4 }
             5 
             6 void main()
             7 {
             8    int a = 100;
             9    for(int i=0;i<100;i++)
            10    {
            11       --a;
            12    }
            13    if(a>0)
            14    {
            15       Foo(a);
            16    }
            17 }


            基本上就是個沒模板,沒類,沒指針的C++了。

            設計就這樣了,明天開始寫詞法分析喔!上面的Lexical Tokens就是給詞法分析用的,因為代碼是字符串,我們先要把整個字符串讀成一個一個的Token,才方便進行語法分析和更深入的處理,比如
            int a = 100;
            要先拆成[type:int] [space] [identifier:a] [space] [operator:=] [space] [integer:100] [seperator:;]
            這個過程就是詞法分析了。

            詞法分析完了得出這些Tokens然后再匹配到

            Variable Declaration:

            type name [= expression];

            才能建立起語法樹來。
            Lexical Tokens中是每種Token對應的正則表達式。

            posted @ 2008-08-05 23:41 陳坤 閱讀(1442) | 評論 (2)編輯 收藏

            我早就想寫一個腳本引擎了,真的。

            事情可以追溯到大一的時候,很想做游戲(雖然后來發現美工成了最大的問題),于是自己寫了一套GUI,用起來還挺爽,但是就是一直覺得缺了個腳本引擎。

            于是,奉天承運,我開始著手腳本引擎的計劃了。

            話說起碼得先跟字符串培養培養感情,而且也是為了以后寫腳本引擎時能省些苦力,還有很多其他因素影響,我決定先寫一個正則表達式引擎。為了方便,我又得封一個性格良好,功能頑強的String類,要真的實現功能頑強,又得搞好Encoding方面的事情,要方便調試程序,又得把Console和IO方面的東西封好。于是我干脆就跟他拼了,封了一個類.Net的小類庫出來。為了好看,名字空間搞得跟.Net的一模一樣,用起來也挺順溜的。

             1 #include "System.h"
             2 
             3 using namespace System;
             4 using namespace System::Text::RegularExpressions;
             5 using namespace System::Windows::Forms;
             6 
             7 int Program(const String& arg)
             8 {
             9     Application::RunConsoleApplication();
            10 
            11     Regex exampleExp("(+\\w+):(+\\z+)");
            12     String exampleString = "hello:哈嘍!!!";
            13 
            14     Int64 startTime = GetTickCount();
            15     Match* m = exampleExp.Match(exampleString);
            16     Int64 endTime = GetTickCount();
            17 
            18     Console::WriteLine("---------KSystem Example Program---------");
            19     Console::WriteLine("Example Regex:\t" + exampleExp.Pattern());
            20     Console::WriteLine("Example String:\t" + exampleString);
            21     Console::WriteLine("Matched Value:\t" + m->Value());
            22     Console::WriteLine(m->Captures[0+ ":" + m->Captures[1]);
            23     Console::WriteLine("Time Cost:\t" + String::ToString(endTime - startTime) + " ms");
            24     Console::WriteLine("-----------------------------------------");
            25 
            26     return 0;
            27 }

            不要問我為什么字符串前面不加L,也不要問我為什么沒有delete那個m,我的庫會干這些事情的。表達式中那個\z是匹配中文字的意思
            運行結果:


            做這么個正則表達式,還輸掉了我一餐pizza。當時跟vczh同學打賭,他說我寫完肯定有bug,我說我肯定沒bug。結果不出意料地有bug,于是一餐華麗的pizza被送進了我們肚子。重要經驗:是個程序必然有bug,恩恩。

            這個正則表達式引擎剛寫出來時性能奇差無比,主要時間耗在了內存分配上。經過一系列優化,vczh也跟著我一起優化了他那個正則表達式引擎,到最后某次性能測試時,我的花了13秒,vczh同學的花了12秒,也有時候是我的更快,視表達式寫法不同而略有差別,基本上平均下來是一樣的。(boost和greta花了40+N秒)

            有了正則表達式引擎,也有了跟字符串幾個月的感情,現在終于開始計劃腳本引擎了。由于還是第一次,總有點畏首畏尾的,我決定先寫一個非常菜的版本。強類型,無閉包,面向過程,支持數組,不支持自定義結構。這是我計劃的CNScript的第一版本,也稱CaiNiaoScript。

            其實我真的想實現的是CNScript的第二個版本,ChinaScript。這會是一個類自然語言寫法的中文腳本引擎。寫起來變量和函數命名絕對會很不習慣,但是寫完之后卻會像一篇文章一樣流利。


            例如:現在用C++,模擬一個人使用某個交通工具去某個地方的行為。

            Class TrafficTool;

            Class Car : public TrafficTool;

            Class Man
            {
               void TravelTo(Point destination, TrafficTool* trafficTool);
            };

            用起來就是

            Man Peter;
            TrafficTool* BMW = new Car();
            Point beijing;

            Peter.TravelTo(beijing, BMW);

            雖然程序員一看就能理解個大概,但是非程序員很難使用或維護它。在將來的CNScript中,也許會是這樣(估計最后不會這么羅嗦):

            有一種東西叫交通工具,汽車就是一種交通工具。
            有一種東西叫人。 //我承認這句話有點怪,語法細節問題需要仔細琢磨,誰有好的建議可以留言給我喔,感激萬分
            有一種東西叫做目的地。

            有一種行為:一個人乘坐一個交通工具去往一個目的地。

            //以上是聲明,以下是使用這幾個類的代碼

            有一個人叫Peter。
            有一個汽車叫寶馬。
            有一個目的地叫北京。

            Peter乘坐寶馬去往北京。

            這樣的代碼,雖然在函數和變量命名時要仔細考慮,但是寫出來的代碼即使是不懂程序的人也能看明白,為的是兼顧游戲開發的各個環節的人員。

            好了,想法到此為止,今晚開始動工CNScript的第一版,CaiNiaoScript! 我會把我每個階段的工作和工作原理都寫在這篇日記中,有興趣的朋友可以跟著一起玩玩喔!

            posted @ 2008-08-05 08:46 陳坤 閱讀(1981) | 評論 (5)編輯 收藏

            久久精品国产99久久久古代| 久久99精品久久久久久不卡| 亚洲av伊人久久综合密臀性色| 国内精品九九久久精品| av国内精品久久久久影院| 精品久久久久中文字| 日韩人妻无码精品久久久不卡 | 久久久久无码专区亚洲av| 久久精品国产只有精品66| 无码专区久久综合久中文字幕| 999久久久无码国产精品| 日韩AV毛片精品久久久| 丰满少妇高潮惨叫久久久| 欧美亚洲日本久久精品| 久久国产亚洲高清观看| 亚洲国产精品嫩草影院久久| 国产91色综合久久免费| 亚洲人成电影网站久久| 国内精品久久久久久不卡影院| 色狠狠久久AV五月综合| 伊人伊成久久人综合网777| 91久久香蕉国产熟女线看| 久久精品人人做人人妻人人玩| 狠狠色丁香久久婷婷综合蜜芽五月| 国产产无码乱码精品久久鸭| 狠狠色综合网站久久久久久久高清 | 久久综合亚洲色HEZYO国产 | 亚洲午夜久久久影院伊人| 久久激情五月丁香伊人| 久久电影网一区| 国产91色综合久久免费| 久久精品九九亚洲精品| 亚洲午夜久久久久久久久久| 久久久久亚洲精品日久生情| 无码任你躁久久久久久| 人人狠狠综合久久亚洲| 亚洲?V乱码久久精品蜜桃 | 国产成人精品三上悠亚久久| 国产精品99久久久久久宅男小说| 久久一区二区三区99| 亚洲欧美日韩久久精品|