我讀Regular Expression Matching: the Virtual Machine Approach現在我嘗試解析一個正則表達式並從中創建一個虛擬機。 標記器工作並創建其標記。這一步之後,我創建令牌流的逆轉波蘭記號所以在最後我從正則表達式a|(b|c)
得到來自正則表達式的虛擬機
a b c | |
。 好了,現在我在那裏停留了一步:我想獲得一個數組
0: split 1, 3
1: match 'a'
2: jump 7
3: split 4, 6
4: match 'b'
5: jump 7
6: match 'c'
7: noop
從上面的數據流。而且我沒有把它做對......我使用輸出數組和堆棧作爲每個令牌的開始位置。首先,將3個值添加到輸出中(並且它是堆棧的起始位置)。
output stack
------------------- ------
0: match 'a' 0: 0
1: match 'b' 1: 1
2: match 'c' 2: 2
隨着|
,我從棧中彈出最後的2個位置,插入在特定位置split
和jump
。這些值是根據當前堆棧長度和我添加的元素數量計算得出的。 最後,我將最後一個元素的新開始位置添加到堆棧中(在這種情況下保持不變)。
output stack
------------------- ------
0: match 'a' 0: 0
1: split 2, 4 1: 1
2: match 'b'
3: jump 5
4: match 'c'
這似乎沒問題。現在,下一個|
被彈出...
output stack
------------------- ------
0: split 1, 3 0: 0
1: match 'a'
2: jump 7
3: split 2, 4
4: match 'b'
5: jump 5
6: match 'c'
這就是問題所在。我必須更新我之前計算的所有地址(第3行和第5行)。這不是我想要的。 我猜,相對地址有相同的問題(至少如果值是負值)。
所以我的問題是,如何從正則表達式創建一個虛擬機。 我是在正確的軌道上(與rpn形式)還是有另一種(和/或更容易)的方式?輸入數組存儲爲整數數組。該split
其實3項-command需要,jump
需要兩個,...
正則表達式的虛擬機標籤會更精確 – 1010
我有一個非常類似的項目,我不認爲你有沒有重新計算的機會。 如果你想到一個樹形結構,你可以通過輸出split來遞歸地啓動一個'|'-node,處理第一個孩子,輸出jump,處理第二個孩子,返回後更新地址'split'和'jump'。在樹中很容易 - 但仍然是重新計算。 –