<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    簡易語言

    數字溝通

     

    用yecc(erlang)寫一個json解析器

      昨天寫了個json的解析器。其實yecc早看過了,只是那時對自己要求太高,想一下子寫個小語言。然后大腦就陷入混亂... 后來注意力轉移了。就不那么急著去開發些難道大的。今天回來一看,覺得都理解了,實踐一下,發現沒人寫json的,太好了。于是就在紙上寫了一下。晚上沒事都敲掉計算機里試試。果然很好用。廢話就不多說了,不專業的我在readme里面已經寫了不少廢話了。主要也不知道git有沒規范約束readme不能寫廢話。其實被google騙了一下,有人寫過json的erlang解析,每次我搜yrl,它就主動搜url文件。還要點一下堅持搜索才行。看看https://github.com/jchris/erlang-json-eep-parser/downloads這上面就是一個解析器,還好我們寫的不是太像,他寫的更精細一點。我寫的更容易使用上手。我寫的就到這下載吧https://github.com/yangyusong/erlang_json_parser。

      接著就是講講內容了,大學學過編譯原理就很容易理解這其中的內容。yrl文件就是erlang中的滿足LALR-1規范的解析生成器,相似于yacc。會有很多文章做解釋,這里不詳述。yrl文件或yacc中的.y這類文件就是給我們寫編譯規則用的,我們寫好一個推理機制,按照規范分解成4部分,放到這一個文件中,那么yecc就可以給我們生成一個符合這個推理規則的解析器,當然這里就是生成.erl的源文件給我們使用,其中會有parse作為默認方法提供給我們解析我們的字符串。

      yrl文件中一共有四部分,其實三部分分別用Nonterminals Terminals Rootsymbol關鍵字來標識,意義很明顯,非終結符,終結符,起始符(這個忘了怎么翻譯)。要解釋一下也行,一個更好的理解方式就是,非終結符可以在推理符號(->)的左邊和右邊,相當于函數作用,最終分析為終結符的組合。終結符只能在推理符號(->)的右邊。意義就是一個符號系統的基本集合。 Rootsymbol是其中一個非終結符,作為推理的起始點。用一棵解析樹來表示的話,Rootsymbol就是根節點。Nonterminals就是樹枝。Terminals就是樹葉。任何一個符合此推理規則的字符串都可以用這樣一棵解析樹表示出來(我就不畫了)。

      除了上面說的三部分就剩下最重要的部分了:推理規則。其實這四部分都是列表,只不過Rootsymbol這個表只有一個元素。規則列表有多條,通常每行一條規則,和erlang一樣用.結束一條規則。
    終結符用單引號引起,冒號后面是我們解析后的erlang表達式。$1,$2,$3這種相似正則表達式規則,也說一下吧,就是對冒號左邊的元素作為列表并從1計數。再搞不懂就發郵局問吧,呵呵。

      那么這樣的一個規則列表就很好建立了,其實這個過程還是有很多規則可以遵循的,其中這里遵循了左遞歸,終結字符先出現的規則優先表達這兩條規則。更多,你還可以畫個有限狀態機,做一下分析,化解,做成閉包,某些運算還要考慮優先級之類。當然這里這樣小的結構基本是最優了,沒什么化解的必要。

    代碼附上
    Nonterminals list object kv_list v_list kv k v. % 7

    Terminals ',' ':' 'element' '[' ']' '{' '}'. % 7

    Rootsymbol object.

    object -> '{' '}' : {}.
    object -> '{' kv_list '}' : { '$2' }.


    kv_list -> kv ',' kv_list : '$1' , '$3'.
    kv_list -> kv : '$1'.

    kv -> k ':' v : {'$1', '$3'}.

    k -> 'element' : '$1'.

    v -> 'element' : '$1'.
    v -> list : '$1'.
    v -> object : '$1'.

    list -> '[' ']' : [].
    list -> '[' v_list ']' : [ '$2' ].

    v_list -> v ',' v_list : '$1' , '$3'.
    v_list -> v.

      其中object,list就是json中最基本的結構。kv_list就是剝離大括號后的鍵值對列表。v_list是剝離中括號的列表。

      再講講這個解析器的使用吧,json_parser就是yrl文件生成的解析器了,我們就用這個解析器來做解析。文件use_json_parser對json_parser的使用做了一個包裝,那就是parser/1函數了,我們給它傳入json字符串就返回解析后的erlang列表。例如我們輸入use_json_parser:parser("{a, b, c}").就會返回[{'{',1},
                                            {atom,1,a},
                                            {',',1},
                                            {atom,1,b},
                                            {',',1},
                                            {atom,1,c},
                                            {'}',1},
                                            {'$end',999}]。
      這個文件還提供一個測試函數了unit_test_()。為了方便大家,我還是講講測試方法吧。在命令行輸入
    cd erlang_json_parser
    erl -pa ./ebin/ -eval "make:all([{d, 'EUNIT'},{outdir, \"./ebin/\"}, debug_info]) ,eunit:test(\"./ebin\",[]),init:stop()"

      參考更多的解析器制作,可以參考erlang官網提供的計算表達式解析,list解析。也可以從其他網站搜到html,xml等的解析,當然如果你看得多一點還會看到aleppo,erlydtl這類的工程。希望更多的人們投入到這些更有意思的開發中。下次再寫yecc,就不寫這么簡單的了。哈哈。不要期待在下一篇里出現哦。


    一種更好的態度,更好的學習、思維方式。它會是網絡極佳的生存方式,你喜歡就對。

    posted on 2011-12-30 23:28 yangyusong 閱讀(3462) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     

    導航

    統計

    常用鏈接

    留言簿(3)

    隨筆分類

    隨筆檔案

    文章分類

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: va亚洲va日韩不卡在线观看| 中文字幕亚洲精品资源网| 亚洲一区二区三区免费| 国产亚洲av片在线观看16女人| 日韩插啊免费视频在线观看| mm1313亚洲精品无码又大又粗 | 亚洲国产精品VA在线观看麻豆 | 在线观看免费播放av片| 国产成人毛片亚洲精品| 国产成人人综合亚洲欧美丁香花| 在线看片免费不卡人成视频| 日日躁狠狠躁狠狠爱免费视频 | 亚洲日韩精品无码专区| 久久亚洲精品无码观看不卡| 免费观看无遮挡www的视频| 亚洲高清无在码在线无弹窗| 四虎www免费人成| 日韩精品免费视频| 国产精品成人亚洲| 亚洲熟伦熟女新五十路熟妇 | 亚洲一卡2卡4卡5卡6卡在线99 | 久久精品亚洲中文字幕无码网站| 在线免费一区二区| 久9久9精品免费观看| 美国免费高清一级毛片| 亚洲男人电影天堂| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 久久亚洲熟女cc98cm| 亚洲男女内射在线播放| 成av免费大片黄在线观看| 亚洲日本一线产区和二线| 亚洲欧洲日产国码久在线观看| 五月婷婷综合免费| 成全视频免费观看在线看| 一级中文字幕免费乱码专区| 亚洲国产乱码最新视频| 亚洲成A∨人片天堂网无码| 久久不见久久见免费影院| 久久99国产乱子伦精品免费| 亚洲国产成人AV在线播放| 亚洲精品**中文毛片|