主頁 >  其他 > Python實作SLR(1)語法分析器,編譯原理yyds!

Python實作SLR(1)語法分析器,編譯原理yyds!

2020-11-15 03:18:42 其他

Python實作SLR(1)語法分析器

實驗課前一天晚上肝了個SLR語法分析器,當時還發朋友圈語法分析器和我晚上總得走一個,從第二天狀態來看,應該是我們倆一起走了(笑

  • 撰寫的時間比較倉促,所以代碼有些地方實作不是很好,存在一些問題,以后有時間的話再來修補一下,比如在對兩個專案規范族進行比較時效率比較低,first集和follow集中對連續多個非終結符推到ε的情況下可能會有bug,但在我的文法定義中特意繞開了ε,勉強能用,
  • 為了方便代碼閱讀,加入了許多注釋后的列印陳述句,將這些列印陳述句取消注釋后運行,能夠告訴你當前這段代碼所做的事,
  • 在撰寫程序中,盡量對模塊進行封裝,把邏輯和文法定義分開,做到文法可以方便地修改,但時間過于倉促可能還是有點小問題,當文法修改時,修改
    getCol函式(該函式將終結符和非終結符映射到action和goto表中相應的列),initProduction函式(該函式定義了文法產生式(拓廣文法),在本文中有28個產生式),source(輸入單詞序列),varset(非終結符集合),terminalset(終結符集合)
    

SLR(1)分析流程

  • 輸入文法
  • 求first集
  • 求follow集
  • 構造LR(0)專案集DFA
  • 構造Action和Goto
  • 按照Action和Goto進行分析

1.主要資料結構定義和基礎函式:

基礎函式

  1. isVariable函式判斷是不是非終結符

  2. isTerminal函式判斷是不是終結

  3. transf(production_set, var)函式 production_set為一個LR(0)專案,嘗試通過var(終結符或非終結符)進行轉移

  4. isSameStatus(status1, status2)函式:判斷status1和status2是不是兩個相同的LR(0)專案

  5. isInPointset(production_set, pointset):#用來檢驗production_set是不是已經存在的point ,如果存在就把point回傳(生成DFA時用到)

資料結構

  1. 產生式采用類來存盤,left和right分別為list,number‘為產生式編號
  2. GraphPoint存盤DFA轉移,transfer為有向邊集合,集合中的一個元素由var(終結符或非終結符),和另一個GraphPoint組成

class Production:
    def __init__(self, left, right, number):
        self.left = left
        self.right = right
        self.number = number

class GraphPoint:

    def __init__(self, begin_production, id):
        self.status = begin_production
        self.transfer = []
        self.id = id

    def add_transfer(self, var, graphPoint):
        self.transfer.append([var, graphPoint])

2.文法定義

1.分析目標代碼:int lexicalanalysis(){ float a; int b; a=1.1; b=2; while(b<100){ b=b+1; a=a+3;}; if(a>5) {b=b-1;} else {b=b+1;}}

2.語法分析器輸入為目標代碼的詞法分析器輸出的單詞序列


source = [[5, "int", " 關鍵字"], [1, "lexicalanalysis", " 識別符號"], [13, "(", " 左括號"], [14, ")", " 右括號"], [20, "{", " 左大括號"],
          [4, "float", " 關鍵字"], [1, "a", " 識別符號"], [15, ";", " 分號"], [5, "int", " 關鍵字"], [1, "b", " 識別符號"],
          [15, ";", " 分號"], [1, "a", " 識別符號"], [12, "=", " 賦值號"], [3, "1.1", " 浮點數"], [15, ";", " 分號"], [1, "b", " 識別符號"],
          [12, "=", " 賦值號"], [2, "2", " 整數"], [15, ";", " 分號"], [8, "while", "  關鍵字"], [13, "(", " 左括號"],
          [1, "b", " 識別符號"], [17, "<", " 小于號"], [2, "100", " 整數"], [14, ")", " 右括號"], [20, "{", " 左大括號"],
          [1, "b", " 識別符號"], [12, "=", " 賦值號"], [1, "b", " 識別符號"], [9, "+", " 加 號"], [2, "1", " 整數"], [15, ";", " 分號"],
          [1, "a", " 識別符號"], [12, "=", " 賦值號"], [1, "a", " 識別符號"], [9, "+", " 加號"], [2, "3", " 整數"], [15, ";", " 分號"],
          [21, "}", " 右大括號"], [15, ";", " 分號"], [6, "if", " 關鍵字"], [13, "(", " 左括號"], [1, "a", " 識別符號"],
          [16, ">", " 大于號"], [2, "5", " 整數"], [14, ")", " 右括號"], [20, "{", " 左大括號"], [1, "b", " 識別符號"],
          [12, "=", " 賦值號"], [1, "b", " 識別符號"], [10, "-", " 減號"], [2, "1", " 整數"], [15, ";", " 分號"], [21, "}", " 右大括號"],
          [7, "else", " 關鍵字"], [20, "{", " 左大括號"], [1, "b", " 識別符號"], [12, "=", " 賦值號"], [1, "b", " 識別符號"],
          [9, "+", " 加號"], [2, "1", " 整數"], [15, ";", " 分號"], [21, "}", " 右大括號"], [21, "}", " 右大括號"]]

3.文法定義:拓廣文法共有28個產生式,0號產生式為保證分析器只有一個接受狀態,而拓廣的產生式,



def initProduction():
    production_list = []
    production = Production(["A1"], ["A"], 0)
    production_list.append(production)
    production = Production(["A"], ["E", "I", "(", ")", "{", "D", "}"], 1)
    production_list.append(production)
    production = Production(["E"], ["int"], 2)
    production_list.append(production)
    production = Production(["E"], ["float"], 3)
    production_list.append(production)
    production = Production(["D"], ["D", ";", "B"], 4)
    production_list.append(production)
    production = Production(["B"], ["F"], 5)
    production_list.append(production)
    production = Production(["B"], ["G"], 6)
    production_list.append(production)
    production = Production(["B"], ["M"], 7)
    production_list.append(production)
    production = Production(["F"], ["E", "I"], 8)
    production_list.append(production)
    production = Production(["G"], ["I", "=", "P"], 9)
    production_list.append(production)
    production = Production(["P"], ["K"], 10)
    production_list.append(production)
    production = Production(["P"], ["K", "+", "P"], 11)
    production_list.append(production)
    production = Production(["P"], ["K", "-", "P"], 12)
    production_list.append(production)
    production = Production(["I"], ["id"], 13)
    production_list.append(production)
    production = Production(["K"], ["I"], 14)
    production_list.append(production)
    production = Production(["K"], ["number"], 15)
    production_list.append(production)
    production = Production(["K"], ["floating"], 16)
    production_list.append(production)
    production = Production(["M"], ["while", "(", "T", ")", "{", "D", ";", "}"], 18)
    production_list.append(production)
    production = Production(["N"], ["if", "(", "T", ")", "{", "D",";", "}", "else", "{", "D", ";","}"], 19)
    production_list.append(production)
    production = Production(["T"], ["K", "L", "K"], 20)
    production_list.append(production)
    production = Production(["L"], [">"], 21)
    production_list.append(production)
    production = Production(["L"], ["<"], 22)
    production_list.append(production)
    production = Production(["L"], [">="], 23)
    production_list.append(production)
    production = Production(["L"], ["<="], 24)
    production_list.append(production)
    production = Production(["L"], ["=="], 25)
    production_list.append(production)
    production = Production(["D"], ["B"], 26)
    production_list.append(production)
    production = Production(["B"], ["N"], 27)
    production_list.append(production)
    return production_list

3.求First集

根據此演算法即可求解first集,第8,9步可以采用遞回的方式進行求解,


def getFirst(production_list, varset, terminalset):
    first_dic = {}
    # 用來標記first集是否計算完畢,防止重復計算浪費時間
    done = {}
    for var in varset:
        first_dic[var] = set()
        done[var] = 0
    # 所有終結符的first集是他自身
    for var in terminalset:
        first_dic[var] = {var}
        done[var] = 1
    # print("初始化后的done",done)
    # print("初始化的first_dic",first_dic)
    for var in varset:
        if done[var] == 0:
            # print("計算",var)
            getFirstForVar(var, first_dic, varset, terminalset, done)
            # print("計算完畢",var)
            # print("此時的done", done)
            # print("此時的first_dic", first_dic)
        else:
            pass
    return first_dic


def getFirstForVar(var, first_dic, varset, terminalset, done):
    # 已經推導過直接結束

    if done[var] == 1:
        # print("我已經推導過了吼")
        return

    # 對非終結符求first集合,先看右邊第一個元素為終結符
    for production in production_list:
        if var in production.left:
            if isTerminal(production.right[0], terminalset):
                first_dic[var].add(production.right[0])
                # 用null表示空字符
            if production.right[0] == "null":
                # print("出現右側為空")
                first_dic[var].add("null")
    # 右邊第一個元素為非終結符
    for production in production_list:
        if var in production.left:
            if isVariable(production.right[0], varset):
                if var == production.right[0]:
                    continue
                if done[production.right[0]] == 0:
                    getFirstForVar(production.right[0], first_dic, varset, terminalset, done)
                if "null" in first_dic[production.right[0]]:
                    first_dic[production.right[0]].remove("null")
                first_dic[var] = first_dic[var] | first_dic[production.right[0]]
                # print("將 ",production.right[0],"的集合 ",first_dic[production.right[0]],"并入",var,"的集合中",first_dic[var],"中","得到",)
            if isVariable(production.right[0], varset) and len(production.right) > 1:

                index = 1
                count = 1
                while isVariable(production.right[index], varset):
                    index = index + 1
                    count = count + 1
                    if index >= len(production.right):
                        break
                i = 0
                while i < count:
                    getFirstForVar(production.right[i], first_dic, varset, terminalset, done)
                    if "null" in first_dic[production.right[i]]:
                        getFirstForVar(production.right[i + 1], first_dic, varset, terminalset, done)
                        first_dic[var] = first_dic[var] | first_dic[production.right[i + 1]]
                    else:
                        break
                    i = i + 1
    # 完成后置為1
    done[var] = 1

4.求解follow集


通過使用非終結符的follow集,提高識別能力,是SLR(1)分析的核心思想,

只有當專案集包含 A→α· ,則action[i,x]= rj,x屬于FOLLOW(A),j為產生式 A→α的編號,通過這種方式可以解決一部分的移進和歸約沖突,

ps:代碼中有坑,如果文法中出現了刁鉆ε,比如幾個非終結符連續推為空,會產生bug,時間原因以及我的文法定義中并不存在ε就沒有解決這個問題,


def getFollow(varset, terminalset, first_dic, production_list):
    follow_dic = {}
    done = {}
    for var in varset:
        follow_dic[var] = set()
        done[var] = 0
    follow_dic["A1"].add("#")
    # for var in terminalset:
    #     follow_dic[var]=set()
    #     done[var] = 0
    for var in follow_dic:
        getFollowForVar(var, varset, terminalset, first_dic, production_list, follow_dic, done)
    return follow_dic


def getFollowForVar(var, varset, terminalset, first_dic, production_list, follow_dic, done):
    if done[var] == 1:
        return
    for production in production_list:
        if var in production.right:
            ##index這里在某些極端情況下有bug,比如多次出現var,index只會回傳最左側的
            if production.right.index(var) != len(production.right) - 1:
                follow_dic[var] = first_dic[production.right[production.right.index(var) + 1]] | follow_dic[var]
            # 沒有考慮右邊有非終結符但是為null的情況
            if production.right[len(production.right) - 1] == var:
                if var != production.left[0]:
                    # print(var, "吸納", production.left[0])
                    getFollowForVar(production.left[0], varset, terminalset, first_dic, production_list, follow_dic,
                                    done)
                    follow_dic[var] = follow_dic[var] | follow_dic[production.left[0]]

    done[var] = 1

5.構建LR(0)專案集DFA

1.首先先定義一個CLOSURE函式,它將會對集合中的產生式狀態進行不斷地擴充,并最終形成一個專案集閉包

def CLOSURE(varset, terminalset, production_set, production_list):

演算法:

2.構建DFA,函式定義

def generatingGraph(begin_production_set, varset, terminalset, production_list):

我們首先使用0號產生式來形成初始LR(0)專案集,產生初始節點(即開頭資料結構中的類),并將它放到一個集合中,每次從集合中取一個節點,來用 每一個var屬于(V | T)嘗試進行轉移,轉移成功后將這條有向邊存入該節點地transfer中,每次轉移后的專案集判斷是否是新專案集,如果是新專案集,則將新專案集放入集合中,當集合為空演算法停止,


# 生成狀態轉移圖
def generatingGraph(begin_production_set, varset, terminalset, production_list):
    global id
    CLOSURE(varset, terminalset, begin_production_set, production_list)
    beginPoint = GraphPoint(begin_production_set, id)
    id = id + 1

    # print("從這個狀態開始!")
    # print(beginPoint.id)
    # for onepro in beginPoint.status:
    #     print(onepro.number, " ", onepro.left, "->", onepro.right, "  ")

    pointset = [beginPoint]
    set = varset | terminalset
    stack = [beginPoint]
    while len(stack) != 0:
        currentPoint = stack.pop()
        ######
        # print("該點被彈出,進行轉移!")
        # print(currentPoint.id)
        # for onepro in currentPoint.status:
        #     print(onepro.number, " ", onepro.left, "->", onepro.right, "  ")

        #####
        for var in set:
            # print("嘗試用",var,"進行轉移")
            result = transf(currentPoint.status, var)
            if len(result) == 0:
                # print(var,"轉移失敗!")
                continue
            else:
                # print(var,"可轉移!")
                # print("將使用result進行轉移!")
                # for onepro in result:
                #     print(onepro.number, " ", onepro.left, "->", onepro.right, "  ")
                # 求出轉移后的閉包
                CLOSURE(varset, terminalset, result, production_list)
                nextpoint = isInPointset(result, pointset)
                if nextpoint is None:
                    # print(var,"轉移為新狀態:")

                    # 新節點壓入尋找堆疊和點集合中,舊節點不能壓入
                    nextpoint = GraphPoint(result, id)
                    id = id + 1
                    pointset.append(nextpoint)
                    stack.append(nextpoint)
                    # print(nextpoint.id)
                    # for onepro in nextpoint.status:
                    #     print(onepro.number, " ", onepro.left, "->", onepro.right, "  ")

                currentPoint.add_transfer(var, nextpoint)
                # print("生成一個新狀態")
                # for onepro in result:
                #     print(onepro.number," ",onepro.left,"->",onepro.right,"  ")

    return pointset


# 形成閉包
def CLOSURE(varset, terminalset, production_set=[], production_list=[]):
    sizebefore = len(production_list)
    sizeafter = -1

    # 用來測驗是不是已經形成閉包,避免進入死回圈
    flag = 0
    for production_in_set in production_set:
        if production_in_set.right.index(".") != len(production_in_set.right) - 1:
            if isVariable(production_in_set.right[production_in_set.right.index(".") + 1], varset):
                flag = 1
    if flag == 0:
        return

    while sizeafter != sizebefore:
        for production_in_set in production_set:
            # 點在最右側就不可能轉移
            if (production_in_set.right.index(".") == len(production_in_set.right) - 1):
                continue
            i = production_in_set.right.index(".") + 1;
            # print(i," length",len(production_in_set.right))
            if isTerminal(production_in_set.right[i], terminalset):
                continue;
            templist = []
            for x in production_list:
                # print(i,len(production_in_set.right))
                if x.left[0] == production_in_set.right[i]:
                    y = copy.deepcopy(x)
                    y.right.insert(0, ".")
                    flag = 0
                    for one in production_set:
                        rightflag = 0;
                        if len(one.right) != len(y.right):
                            rightflag = 1
                        else:
                            for j in range(0, len(y.right)):
                                if one.right[j] != y.right[j]:
                                    rightflag = 1
                        if one.left[0] == y.left[0] and rightflag == 0:
                            flag = 1
                    if flag == 0:
                        templist.append(y)
            sizebefore = len(production_set)
            production_set.extend(templist)
            sizeafter = len(production_set)

6.構造Action和Goto表

演算法:

演算法中的(1)(2)思想類似于計算機網路中的洪泛控制,將初始節點放入一個集合中,從集合中取一個節點,從一個節點走出它的所有有向邊,并將這個節點標記為已經走過,將到達所有的之前沒有走過的節點放入集合中,如此以往,直到集合為空,代碼中的一些列印出錯的陳述句為檢測是否存在沖突的陳述句,由于撰寫時間限制原因,大多數的沖突可被測出,但少部分沖突仍然不可見(天坑),

演算法(3)(4)通過遍歷專案集中的產生式狀態即可判斷,


#Cell為Action中的一個元素,do表示動作,which表示數字,如轉移的狀態或采用歸約的產生式序號,done為是否已經走過,類似于洪泛控制的作用
class Cell:
    def __init__(self):
        self.do = -1
        self.which = -1
        self.done = 0

def initActionAndGoto(pointset, varset, terminalset, begin, follow_dic):
    Action = [[Cell() for i in range(len(terminalset))] for j in range(len(pointset))]
    Goto = [[-1 for i in range(len(varset))] for j in range(len(pointset))]
    for point in pointset:
        # 轉移狀態
        for tran in point.transfer:
            if isVariable(tran[0], varset):
                if Goto[point.id][getCol(tran[0])] != -1:
                    print("出錯404")
                Goto[point.id][getCol(tran[0])] = tran[1].id
            else:
                if Action[point.id][getCol(tran[0])].done == 1:
                    print("出錯403")
                Action[point.id][getCol(tran[0])].done = 1
                Action[point.id][getCol(tran[0])].do = "S"
                Action[point.id][getCol(tran[0])].which = tran[1].id
        for production in point.status:
            if production.right.index(".") == len(production.right) - 1 and production.left[0] == begin:
                if Action[point.id][getCol("#")].done == 1:
                    print("出錯415")
                Action[point.id][getCol("#")].do = "acc"
                Action[point.id][getCol("#")].done = 1
            if production.right.index(".") == len(production.right) - 1 and production.left[0] != begin:
                # 在follow集中才可歸約
                for terminal in terminalset:
                    if terminal in follow_dic[production.left[0]]:

                        # 沖突檢測
                        if Action[point.id][getCol(terminal)].done == 1:
                            for xx in point.status:
                                print(xx.number, "  ", xx.left, "->", xx.right)
                            print("Action表", point.id, "行", getCol(terminal), "列沖突")
                            print("原本", Action[point.id][getCol(terminal)].do, Action[point.id][getCol(terminal)].which)
                            print("現在", "R", production.number)
                            print("出錯416")
                        Action[point.id][getCol(terminal)].do = "R"
                        Action[point.id][getCol(terminal)].done = 1
                        # 采用該產生式歸約
                        Action[point.id][getCol(terminal)].which = production.number

    return Action, Goto

7.根據Action和Goto進行語法分析

演算法思想:

開始時句型前綴堆疊和狀態站分別壓入#和0狀態,

回圈:

如果表中為si,則將緩沖區第一個元素壓入句型前綴堆疊,并將 i(狀態)壓入狀態堆疊

如果表中為ri , 則采用第i個運算式進行歸約,彈出的元素個數為i個運算式的右側的元素個數,之后根據堆疊頂狀態和歸約得到的非終結符查看GOTO表,查找當前狀態,并將當前狀態和規約得到的非終結符分別入堆疊,

如果表中為error!,恭喜出錯,去找bug吧(也有可能是你的輸入不符合當前文法,文法沖突也會導致這種情況),

如果表中為acc,恭喜成功,


# SLR分析開始
def SLR(Action, Goto, source, production_list):
    source.append([0, "#", "結束符"])
    statusstack = [0]
    sentence_stack = ["#"]
    print(source)
    while 1:
        print("*****************************************")
        print("緩沖區剩余元素", source)
        terminal = source.pop(0)

        print("狀態堆疊", statusstack)
        print("句型堆疊", sentence_stack)
        # 移進
        if Action[statusstack[len(statusstack) - 1]][terminal[0]].do == "S":
            print("動作: 移入操作,從緩沖區中讀取",terminal[1],"元素進行移入,并根據Action壓入",Action[statusstack[len(statusstack) - 1]][terminal[0]].which,"狀態")
            statusstack.append(Action[statusstack[len(statusstack) - 1]][terminal[0]].which)
            sentence_stack.append(terminal[1])
        elif Action[statusstack[len(statusstack) - 1]][terminal[0]].do == "R":
            # 歸約
            # 記錄歸約產生式
            r_production = 0
            for production in production_list:
                if production.number == Action[statusstack[len(statusstack) - 1]][terminal[0]].which:
                    r_production = production
            for i in range(len(r_production.right)):
                statusstack.pop()
                sentence_stack.pop()
            statusstack.append(Goto[statusstack[len(statusstack) - 1]][getCol(r_production.left[0])])
            print("動作: 歸約操作,根據Action表利用第",r_production.number,"個產生式歸約")
            sentence_stack.append(r_production.left[0])
            source.insert(0, terminal)

        elif Action[statusstack[len(statusstack) - 1]][terminal[0]].do == "acc":

            print("!!!!!!!!!!語意分析完成!!!!!!!!!!!!!!")
            break;
        else:
            print("error 462!");

8.運行與測驗


source = [[5, "int", " 關鍵字"], [1, "lexicalanalysis", " 識別符號"], [13, "(", " 左括號"], [14, ")", " 右括號"], [20, "{", " 左大括號"],
          [4, "float", " 關鍵字"], [1, "a", " 識別符號"], [15, ";", " 分號"], [5, "int", " 關鍵字"], [1, "b", " 識別符號"],
          [15, ";", " 分號"], [1, "a", " 識別符號"], [12, "=", " 賦值號"], [3, "1.1", " 浮點數"], [15, ";", " 分號"], [1, "b", " 識別符號"],
          [12, "=", " 賦值號"], [2, "2", " 整數"], [15, ";", " 分號"], [8, "while", "  關鍵字"], [13, "(", " 左括號"],
          [1, "b", " 識別符號"], [17, "<", " 小于號"], [2, "100", " 整數"], [14, ")", " 右括號"], [20, "{", " 左大括號"],
          [1, "b", " 識別符號"], [12, "=", " 賦值號"], [1, "b", " 識別符號"], [9, "+", " 加 號"], [2, "1", " 整數"], [15, ";", " 分號"],
          [1, "a", " 識別符號"], [12, "=", " 賦值號"], [1, "a", " 識別符號"], [9, "+", " 加號"], [2, "3", " 整數"], [15, ";", " 分號"],
          [21, "}", " 右大括號"], [15, ";", " 分號"], [6, "if", " 關鍵字"], [13, "(", " 左括號"], [1, "a", " 識別符號"],
          [16, ">", " 大于號"], [2, "5", " 整數"], [14, ")", " 右括號"], [20, "{", " 左大括號"], [1, "b", " 識別符號"],
          [12, "=", " 賦值號"], [1, "b", " 識別符號"], [10, "-", " 減號"], [2, "1", " 整數"], [15, ";", " 分號"], [21, "}", " 右大括號"],
          [7, "else", " 關鍵字"], [20, "{", " 左大括號"], [1, "b", " 識別符號"], [12, "=", " 賦值號"], [1, "b", " 識別符號"],
          [9, "+", " 加號"], [2, "1", " 整數"], [15, ";", " 分號"], [21, "}", " 右大括號"], [21, "}", " 右大括號"]]
id = 0
varset = {"A1", "A", "E", "I", "D", "F", "G", "M", "P", "K", "T", "L", "B","N"}
terminalset = {"(", ")", "{", "}", ";", "int", "float", "number", "floating", "while", "if", "else", ">", "<", ">=",
               "<=", "==", "=", "#", "+", "-", "id"}
production_list = initProduction()
first_dic = getFirst(production_list, varset, terminalset)
# for x in first_dic:
#     print(x," : ",first_dic[x])
follow_dic = getFollow(varset, terminalset, first_dic, production_list)
# print("follow:")
# for x in follow_dic:
#     print(x, ":", follow_dic[x])
production = Production(["A1"], [".", "A"], 0)

production_set = [production]
# for x in production_set:
#     print(x.number," ",x.left,"->",x.right,"  ")

pointset = generatingGraph(production_set, varset, terminalset, production_list)


begin = "A1"
Action, Goto = initActionAndGoto(pointset, varset, terminalset, begin, follow_dic)
print("**********************GOTO***********************************")
for i in range(len(Goto)):
    print(i, end=" ")
    for j in range(len(Goto[i])):
        print("%3d" % Goto[i][j], end=" ")
    print("")

print("**********************Action***********************************")
for i in range(len(Action)):
    print("%2d" % i, end=": ")
    for j in range(len(Action[i])):
        if (Action[i][j].done == 0):
            print("error!", end="   ")
        else:
            print("%3s" % Action[i][j].do, "%2d" % Action[i][j].which, end="   ")
    print("")

SLR(Action, Goto, source, production_list)

結果:

GOTO表(區域):(60*14)

Action表(區域):60*22

規約程序(區域):共142次

開始:

結束:

完整代碼編譯原理結課會放在博客里

2020.11.12

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/216469.html

標籤:其他

上一篇:2020年Python最新面試題(一):Python基礎

下一篇:100個numpy問題50-100

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more