<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 閱讀(3470) 評論(0)  編輯  收藏


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


    網站導航:
     

    導航

    統計

    常用鏈接

    留言簿(3)

    隨筆分類

    隨筆檔案

    文章分類

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 久久久亚洲AV波多野结衣 | 色在线亚洲视频www| 天天看免费高清影视| 国产高清视频免费在线观看| 亚洲成a人片在线观看久| 精品熟女少妇aⅴ免费久久 | 亚洲国产成人AV网站| 久久亚洲AV无码精品色午夜麻| 国产成人精品日本亚洲专区6| 亚洲无人区午夜福利码高清完整版| 青青免费在线视频| 亚洲精品9999久久久久无码| 亚洲国产精品综合久久网各| 亚洲精品日韩专区silk| 亚洲国产精品久久久久婷婷老年 | 狠狠色伊人亚洲综合网站色| 亚欧日韩毛片在线看免费网站| h视频在线免费观看| 亚洲大码熟女在线观看| 日产久久强奸免费的看| 九九免费精品视频在这里| 亚洲自偷自偷在线制服| 亚洲av福利无码无一区二区| 亚洲白色白色在线播放| 亚洲国产精品无码久久98| 大桥未久亚洲无av码在线| 亚洲国产精品精华液| 天堂亚洲免费视频| 亚洲精品私拍国产福利在线| 亚洲人成电影在在线观看网色| 2020国产精品亚洲综合网| 香蕉视频在线观看免费| 99久久国产免费中文无字幕| 日韩欧美一区二区三区免费观看 | 污污免费在线观看| 99在线观看精品免费99| 亚洲A丁香五香天堂网| 亚洲经典在线观看| a毛片免费观看完整| 亚洲人成电影网站| 亚洲码在线中文在线观看|