LR0アナラむザヌを䜜成したす。 耇雑なこずに぀いお簡単な蚀葉で

はじめに





こんにちは

ロシア語では、このアルゎリズムの簡単でわかりやすい説明は芋぀かりたせんでした。 このギャップを埋めるこずにしたした。 たず、それは䜕ですか LR0パヌサヌは、䞻にパヌサヌです。 パヌサヌの目的は、トヌクンの入力ストリヌム字句アナラむザヌが入力文字ストリヌムに基づいお生成する蚀語の基本芁玠、トヌクンの䟋は数字、コンマ、文字を凊理し、それを特定の圢匏で指定された蚀語の説明ず比范するこずです。 比范は、特定のデヌタ構造ほずんどの堎合ツリヌの構築で構成されたす。 さらに、この構造は次の段階であるセマンティック分析に進み、コンパむラはすでにツリヌの意味を理解しようずしおいたす。



パヌサヌには、アップストリヌムずダりンストリヌムの2぀のクラスがありたす。 前者は、入力トヌクンである葉から始たるツリヌを構築したすが、埌者は、逆に、ツリヌのルヌトから始たりたす。 実際、LRは、アナラむザヌがストリヌムを巊から右L-「巊」に読み取り、䞋から䞊にツリヌを構築するこずを意味したす混乱を起こさずに右を意味する文字Rを入力したす。 むンデックス0は、次のトヌクンをプレビュヌせず、珟圚のトヌクンでのみ機胜するこずを意味したす。 このタむプのアナラむザヌを遞択する利点は䜕ですか



欠点もありたす









甚語





端末蚘号  terminal は、ナヌザヌがアナラむザヌに䞎えるこずができる蚘号です。この堎合、これらはトヌクンです。

非終端 蚘号  nonterminal 、 nonterminal -蚀語のオブゞェクトを瀺す蚘号。 たずえば、蚘号Aは甚語であるずしたしょう。 もちろん、耇数文字の名前Aではなくtermを遞択できたす。

文脈自由文法  CFG -フォヌムのルヌルのセット 画像 ここで、Aは非端末、wは端末ず非端末の任意のコレクションです。 この蚘事では、この文脈のない意味で、単に文法を䜿甚したす。

アナラむザヌを䜜成する文法の小さな䟋

画像

この文法は、0ず1の2぀の数倀に察する䞍完党な算術挔算のセットを蚘述しおいたす。文法は、蚀語の蚘述です。 入力ストリヌムが私たちの蚀語に属しおいるか、どこかで構文゚ラヌ1 + 1の代わりに1+を曞いたかどうかをチェックするために、開始の非終端から始たるこの芏則に埓っお入力ストリヌムを取埗する方法を探しおいたすEがありたす。 1 + 1の堎合、パスはそのようなEになり、ルヌル2、E + F、ルヌル1、F + F、ルヌル4、T + F、ルヌル8、1 + F、再び4、1 + T、最埌に8番目を適甚し、 1 +1。ご芧のずおり、入力文字列を取埗できたした。これは、構文的に正しいこずを意味したす。

これで、アナラむザヌの名前のRずいう文字を説明できたす。 これは、ルヌルの極右郚分から公理に移る、぀たり、元の1を収集するより単玔なルヌル7および8から進むこずを意味したす。 LアナラむザヌLLは、ルヌルの巊偎の郚分から次の分析方向を遞択しようずしたす。



有限状態マシン  FSM に぀いおも蚀及する䟡倀がありたす。 これは、䞀連の状態ず入力ストリヌムを持぀モデルです。 マシンは初期状態から起動し、珟圚のシンボルず入力シンボルに基づいお状態を倉曎したす。 ぀たり、状態0から開始し、aが入力に入るず、オヌトマトンは状態1になり、bが状態2になりたす。遷移の仕組みは、衚によっお䞎えられたす。列は珟圚の状態、列は入力蚘号です。



アルゎリズム





アナラむザヌを機胜させるには、いく぀かのこずが必芁です。





ここでは、アナラむザヌがどのように機胜するかを明確にする必芁がありたす。 珟圚の状態は、スタックの䞀番䞊の状態です。 アクションのテヌブルを芋おくださいむンデックスは珟圚の入力シンボルず珟圚の状態です。 このテヌブルには4皮類のレコヌドがありたす。





コヌド圢匏では、次のようになりたす。

  1. スタック。 プッシュ 状態[ 0 ]  ;
  2. while  が受け入れられたす
  3. {
  4. 状態* st =スタック。 トップ   ;
  5. 末端項= s [ inp_pos ] ;
  6. if   terms。IsTerm  term  
  7. ゚ラヌ  ;
  8. アクション*アクション= actionTable。 Get  st、term  ;
  9. if  アクション
  10. ゚ラヌ  ;
  11. スむッチ アクション- >タむプ  
  12. {
  13. ケヌス ActionAccept 
  14. 受け入れられた= true ;
  15. 䌑憩 ;
  16. case ActionShift 
  17. inp_pos ++ ;
  18. スタック。 プッシュ アクション- >状態   ;
  19. 䌑憩 ;
  20. ケヌス ActionReduce 
  21. ルヌル*ルヌル=アクション- >ルヌル  ;
  22. スタック。 pop ルヌル- >サむズ   ;
  23. 状態* transferState = transferTable。 Get スタック。 トップ   、ルヌル- >巊   ;
  24. if   transferState 
  25. ゚ラヌ  ;
  26. スタック。 push  transferState  ;
  27. 䌑憩 ;
  28. }
  29. }




ご芧のずおり、分析自䜓に耇雑なこずはありたせん。 ただし、党䜓のトリックは、これらのトリッキヌなテヌブルを䜜成するこずです。 たず、パヌサヌの状態を把握したしょう。 これは、アルゎリズムのかなり重芁な郚分です。 いいえ、これは単なる数字ではありたせん。 いく぀かの新しい抂念を導入する必芁がありたす。

たず、これらはアむテムです。 これは、マヌカヌずいう新しいプロパティを持぀ルヌルです。 マヌカヌは、珟圚期埅しおいる芁玠を瀺したす。 したがっお、各ルヌルはn + 1個のトヌクンを生成したす。nはルヌルの右偎の文字数です。 たずえば、ルヌル3を䜿甚したす。円の䞭のプラス蚘号は、マヌカヌの堎所を瀺したす。

画像

たずえば、2番目の段萜のマヌカヌは、珟圚の文字にマむナス蚘号が衚瀺されるこずを瀺しおいたす。 耇数のアむテムを組み合わせるず、アむテムのセットになりたす。 実際には、状態は特定の方法で䞀緒に組み立おられたアむテムのセットです。



ただし、状態を操䜜するには、最初にセットを閉じる必芁がありたす。 これは、完党なアナラむザヌブランチを取埗するこずを意味したす。 ぀たり、セット内にマヌカヌが非終端点を指すポむントがある堎合そしお、この堎合、すべおの非終端点は巊偎の郚分です、察応する非終端点を「デプロむ」する必芁がありたす。 これは、巊郚分がこの非終端であるアむテムを远加するだけで起こり、マヌカヌは最初の文字を指したす。 単独で、再垰的に展開したす。新しく远加された段萜で最初の文字が非終端蚘号である堎合は、閉じたす。 フルセットを取埗するたで。 ポむントが1぀しかないセット前の䟋では3番を閉じたす。

画像

Fを展開するず、ポむント2、3、4が埗られたす。3ず4では、再びFを展開するよう提案されたすが、これらのルヌルは既にセットにあるので、スキップしたす。 しかし、Tがデプロむされおいないため、5ず6が埗られたす。すべお、クロヌゞャヌの準備ができたした。



  1. for  itemsetのclosed_item 
  2. {
  3. if  closed_item。isClose 
  4. 続ける ;
  5. 芁玠マヌカヌ= closed_item。 マヌカヌ   ;
  6. if マヌカヌ。 タむプ    = ElementNonTerm 
  7. {
  8. closed_item。 isClose = true ;
  9. 続ける ;
  10. }
  11. NonTerminal nonTerm =マヌカヌ。 NonTerm   ;
  12. item = allitems- > First  0 、nonTerm  ;
  13. while   item。isend   
  14. {
  15. if   itemset。exists  item  
  16. アむテムセット。 远加 アむテム ;
  17. アむテム。 next  0 、nonTerm  ;
  18. }
  19. closed_item。 isClose = true ;
  20. }


状態が䜕であるかを理解したら、それらの構築を開始できたす。 最初に、出力の基瀎であり、最埌に到達する必芁がある新しいルヌルを導入したす。

画像



もちろん、最初の状態は、このルヌルに基づいお、マヌカヌをEに向けおアむテムを閉じるこずです。ここで、䞀時的な有限状態マシンのテヌブルの構築を開始したす。これは、遷移テヌブルずアクションテヌブルの基盀ずしお機胜したす。 マヌカヌが指すシンボルの基準に埓っお、状態をグルヌプに分けたす。 この䟋のクロヌゞャでは、Fグルヌプ、Tグルヌプ、0グルヌプ、1グルヌプの4぀のグルヌプがありたす。 各グルヌプは、新しい状態ぞの移行です。 遷移からの最初のむンデックスは、実際にグルヌプ化するシンボルF、T、0、1です。 2番目のむンデックスは珟圚の状態です。 そしお、テヌブル内の倀は、枡す状態です。 したがっお、4぀の新しい状態を取埗したす。 それらを構築するのは非垞に簡単です-各ポむントでグルヌプ内でond䜍眮のマヌカヌを右に移動し、結果セットを閉じたす。 これは新しい状態になりたす。



  1. firstState。 远加 項目。 最初    ;
  2. firstState。 MakeClosure   ;
  3. 状態。 add  firstState  ;
  4. size_t state_idx = 0 ;
  5. while  state_idx < states。size   
  6. {
  7. 状態* st =状態[ state_idx ] ;
  8. GroupedItems group = st- > Group   ;
  9. for  groupのgroup_class 
  10. {
  11. if  group_class- > first。 タむプ   == ElementEnd 
  12. 続ける ;
  13. State newState   items、states。Size    ;
  14. for  group_classのgroup_item 
  15. newState。 远加  group_item、group_item。MarkerInt   + 1  ;
  16. newState。 MakeClosure   ;
  17. 状態oldState =状態。 怜玢  newState 
  18. if   oldState 
  19. {
  20. 状態。 add  newState  ;
  21. fsmTable。 Add  st、group_class- > first、newState  ;
  22. }
  23. 他に
  24. fsmTable。 Add  st、group_class- > first、oldState  ;
  25. }
  26. state_idx ++ ;
  27. }




遷移テヌブルは非垞に簡単に構築されたす-むンデックスが非終端であるFSMテヌブルから列を転送したす。



アクションテヌブルはもう少し興味深いものです。 たた、パヌツはFSMからタヌミナルむンデックス付きの列に転送されたすが、元の宇宙船テヌブルに蚘録された状態パラメヌタヌを䜿甚したシフトアクションはテヌブルセルに曞き蟌たれたす。 次に、入力行の終わりを瀺す新しい列「$」を远加したす。 この列には、受け入れられたむベントを入力したす。これは、むンデックス状態にアむテムが含たれおいる堎合に曞き蟌たれたす 画像 。 これは成功を意味し、䞻芁なルヌルに倉わり、同時に入力ストリヌムが終了したす。 次に、畳み蟌みアクションがありたす。 アむテムがある各州に぀いお 画像 、ここでwは端末ず非端末の任意の組み合わせで、行党䜓もちろん、他のコマンドで占有されおいないフリヌセルのみを意味したすのreduceコマンドず、このアむテムが属する察応するルヌルのパラメヌタヌを蚘述したす。



  1. fsmTable。 FeedTransferTable  transferTable  ;
  2. fsmTable。 FeedActionTable  actionTable  ;
  3. アむテムendItem =アむテム。 GetItem  1 、 'S' 、Elements  "E" 、nonTerms   ;
  4. for  st in states 
  5. if  st。HaveItem  endItem  
  6. actionTable。 Add  st、 '$' 、 new Action    ;
  7. for  st in states 
  8. {
  9. ItemListリスト= st。 GetReducable   ;
  10. for リスト内のlistItem 
  11. actionTable。 Add  st、 new Action  listItem。GetRule     ;
  12. }




文孊





コンパむラ原則、テクニック、およびツヌル、1986幎、アルフレッドV.アホ、ラビセティ、ゞェフリヌD.りルマン



All Articles