簡體   English   中英

用於HTML Markdown源代碼的詞法分析器(java)

[英]Lexical analyzer (java) for HTML Markdown source code

我甚至不知道從哪里開始編寫逐字符詞法分析器。 我根據我給出的規則和細節為Markdown語言(特別是HTML)編寫了BNF語法規則,因此不需要添加任何語法規則。 我現在必須設計並實現一個逐字符的詞法分析器,它將我的Markdown語言中的源文件的詞位分成標記。 這是我的BNF GRAMMAR:

終端:

#DOCUMENT BEGIN,
#DOCUMENT END
#HEAD BEGIN,
#HEAD END,
#TITLE BEGIN,
#TITLE END,
#PARAGRAPH BEGIN,
#PARAGRAPH END,
#BOLD BEGIN,
#BOLD END,
#ITALICS BEGIN,
#ITALICS END,
#LIST BEGIN,
#LIST END,
#ITEM BEGIN,
#ITEM END,
#LINK BEGIN,
#TEXT,
#ADDRESS,
#LINK END,
#DEFINE BEGIN,
#NAME,
#VALUE,
#DEFINE END,
#USE BEGIN,
#USE END

請注意,這些終端不區分大小寫。

非終端:

<document> ::= #DOCUMENT BEGIN <macro-­‐define> <head> <body> #DOCUMENT END

<head> ::= #HEAD BEGIN <title> #HEAD END | ε

<title> ::= #TITLE BEGIN <text> #TITLE END | ε

<body> ::= <inner-­‐text> <body>
           | <paragraph> <body>
           | <bold> <body>
           | <italics> <body>
           | <list> <body>
           | ε

<paragraph> ::= #PARAGRAPH BEGIN <macro-­‐define> <inner-­‐paragraph> #PARAGRAPH END

<inner-­‐paragraph> ::= <inner-­‐text> <inner-­‐paragraph>
                      | <bold> <inner-­‐paragraph>
                      | <italics> <inner-­‐paragraph>
                      | <list> <inner-­‐paragraph>
                      | ε

<inner-­‐text> ::= <macro-­‐use> <inner-­‐text>
                  | <text> <inner-­‐text>
                  | ε

<macro-­‐define> ::= #DEFINE BEGIN #NAME <text> #VALUE <body> #DEFINE END <macro-­‐define>
                    | ε

<macro-­‐use> ::= #USE BEGIN <text> #USE END | ε

<bold> ::= #BOLD BEGIN <macro-­‐define> <inner-­‐text> #BOLD END

<italics> ::= #ITALICS BEGIN <macro-­‐define> <inner-­‐text> #ITALICS END

<link> ::= #LINK BEGIN #TEXT <text> #ADDRESS <text> #LINK END

<list> ::= #LIST BEGIN #ITEM BEGIN <macro-­‐define> <inner-­‐list> #ITEM END <list-­‐items> #LIST END

<list-­‐items> ::= #ITEM BEGIN <macro-­‐define> <inner-­‐list> #ITEM END <list-­‐items> | ε

<inner-­‐list> ::= | <bold> <inner-­‐list>
                  | <italics> <inner-­‐list>
                  | <list><inner-­‐list>
                  | <inner-­‐text> <inner-­‐list>
                  | ε

<text> ::= Any plain text | ε

我們可以假設HTML字符(如“<”,“>”,“&”和“/”不會出現在源文件的任何文本中。 我們還可以假設“#”僅出現在我們的其中一個Markdown注釋之前(例如,#DOCUMENT)。 我認為最好有單獨的Java類來表示令牌對象,例如: DocumentBegin,DocumentEnd,ParagraphBegin,ParagraphEnd等。遇到的任何詞匯錯誤(例如,#DOC BEGIN)都應該作為輸出報告給控制台錯誤信息盡可能。 遇到第一個錯誤后,編譯器應該退出。 如果遇到錯誤,則不應創建輸出文件。

我的問題是,我知道詞法分析器應該做什么,但老實說,我不知道從哪里開始編碼/實現。 如果您需要更多解釋問題的原因,請詢問,我可以盡力解釋。 這是我們班上應有的一個大項目的一部分。 我無法完成這部分並且失去了很多分,但現在我只需要了解它,所以一旦我們對它進行了測試,我就不會迷失方向。

好的,這已經晚了一點,但我們走了。

詞法分析器通常與語法(和BNF表示法)相關聯,但兩者實際上有點不同。

詞法分析器將字符轉換為令牌,令牌在某種程度上處理語法的“原子”,而解析器將令牌轉換為某種中間結構(通常是樹)。 只關注詞法分析器部分,您可以將其視為輸入的低通處理,就像我們將字母處理成單詞一樣。

由於您已經擁有BNF語法,因此您已經知道要使用的所有令牌(結束詞),因此請將它們放入列表中。 這個想法是如何快速決定哪個系列的字母將映射到列表中的每個項目。 例如

#, D, E, F, I, N, E, <whitespace> => #DEFINE
#, D, O, C, U, M, E, N, T, <whitespace> => #DOCUMENT
B, E, G, I, N, <whitespace> => BEGIN
E, N, D, <whitespace> => END

在解析過程中會出現一些問題:

首先,你要做很多比較。 讀入的第一個字符可能是'#',如果是,那么您仍然可以匹配超過20個項目。 這意味着你必須繼續你的匹配到下一個角色,如果它是'D'仍然意味着有兩個可能的匹配'#DEFINE'和'#DOCUMENT'。

其次,如果你在處理'#BEGIN'之后有'#BEGIN'和'#BEGINNING'這樣的詞,那么在你抓住下一個字符之前,你無法決定兩者之間的關系。 抓住系統中的下一個字符,認為該字符的“消耗”使下一個令牌的處理變得復雜。 可能需要窺視或前瞻,但這些增加了邏輯中的復雜性以決定生成哪些令牌。

第三,你有一個外卡“文本”令牌。 該令牌幾乎可以匹配任何內容,因此您需要針對所有其他令牌進行檢查,以確保令牌生成邏輯始終知道它應生成哪個令牌。

理想情況下,令牌生成器(Lexer)不依賴於任何解析來“知道”下一個令牌; 然而,有些語言非常復雜,解析器會向Lexer提供“提示”。 避免使用這些類型的系統可以實現更清晰的編譯器實現; 遺憾的是,在一些已有的語言中,並不總是可以用這種方式構建東西。

所以,要知道你知道該怎么做(在某種意義上你可能已經擁有過),你是怎么做到的?

好吧,你需要某種索引來跟蹤你消耗的字符(已經完全轉換為標記),這樣你就不會意外地讓字符對令牌流產生雙重影響。 如果你要向前看,你需要一個“向前看”的第二個指針,你可能想要限制前瞻的數量(使邏輯變得更加困難)。

然后,您需要未知數量的數據結構(稱為令牌)。 雖然並非總是需要這樣做,但我建議跟蹤令牌中的起始行號,起始字符索引,結束行號和結束字符索引。 它使調試變得更容易。 此外,最好“捕獲”令牌中的子字符串。 你可以這么稱呼你,但有些人稱之為令牌的“形象”。

當然,如果您的解析器可以區分不同類型的令牌,那么您應該通過某種方式將該令牌的類型存儲在令牌中(或與令牌中)。 偶爾一個人有一個標記“價值”的概念,它也可能存儲。

經過一番努力之后,你應該能夠將一串字符推入Lexer,然后出現一系列令牌。 祝好運。

我在Java中發現的最好的(也就是我所知道的)詞法分析器稱為JFlex。 我們在大學使用它來標記語言,我已經商業化地使用它來為應用程序中的特定領域語言創建語法高亮。

JFlex詞法分析儀

http://jflex.de/

杯解析器

http://www2.cs.tum.edu/projects/cup/

關於LALR(1)Parsers的一點點

http://en.wikipedia.org/wiki/LALR_parser

如果您需要示例(即示例代碼)給我發消息,我會給您發送一些注意事項。 雖然我確信某些大學網站(即普林斯頓大學)可能有什么東西,但快速谷歌並沒有顯示任何有用的東西。

干杯,

約翰

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM