1 / 17

3.2 字句解析のプログラム (1)一般的構成

3.2 字句解析のプログラム (1)一般的構成. 1文読込み (注釈部分の削除). ソースプログラム 1文(テキスト. 数値/文字列/ 名前/区切り記号. 単純字句解析. 12.3 , E , -15, 12.3 , E5 , + , =, > , <, … , while, if, ・・・, ” abcdefg ”. 文構成単位の 字句解析. トークン. ソース プログラム ファイル. エディタ用 テキスト ボックス. 12.3E-15, 12.3E5 ==,++ , +=, >=, … , while, if, ・・・,

Download Presentation

3.2 字句解析のプログラム (1)一般的構成

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 3.2 字句解析のプログラム(1)一般的構成3.2 字句解析のプログラム(1)一般的構成 1文読込み (注釈部分の削除) ソースプログラム 1文(テキスト 数値/文字列/ 名前/区切り記号 単純字句解析 12.3,E,-15, 12.3,E5,+,=, >,<,…, while, if,・・・,”abcdefg” 文構成単位の 字句解析 トークン ソース プログラム ファイル エディタ用 テキスト ボックス 12.3E-15, 12.3E5 ==,++,+=, >=, … , while, if,・・・, “abcdefg” 構文解析

  2. (2)1文読込み(注釈部分の削除) VBに似た言語の1文読込み ①1行に1文が基本。 ②1行に複文のときコロン(:)で区切る ③複数行にまたがるときはアンダーライン(_)を最後に付ける。 ④注釈の先頭はシングルクォート(‘)

  3. 1文読込みの状態遷移 行終り 通常 モード 文字列内部 引用符(“) 引用符(“) 引用符直後 行終り エラー 状態遷移図 引用符(“) 引用符以外の文字 継続指定“ _” 行終りまで無視(継続行用) 行終り以外 行終り 行終り以外 行終りまで無視(注釈用) 注釈指定“‘” 行終り 行終り “:”または行終り 終了 【演習】C言語の1文読み込みの状態遷移図を書け。 ①8進数はないものとする。 ②\n,\”等の記法が許されるものとする。

  4. 参考(1) Private Alltext As String Private ScanMode As Short Private Function scanComment() As String Dim CH1, CH2 As String: Dim LN As Integer CH1 = Microsoft.VisualBasic.Left(Alltext, 1) Select Case ScanMode Case 0 CH2 = Microsoft.VisualBasic.Left(Alltext, 2) If CH1 = " " Or CH1 = "" Or CH1 = vbTab Then LN = Microsoft.VisualBasic.Len(Alltext) Alltext = Microsoft.VisualBasic.Right(Alltext, LN - 1) scanComment = " " ElseIf CH2 = vbCrLf Then LN = Microsoft.VisualBasic.Len(Alltext) Alltext = Microsoft.VisualBasic.Right(Alltext, LN - 2) scanComment = " " ElseIf CH2 = "//" Then LN = Microsoft.VisualBasic.Len(Alltext) Alltext = Microsoft.VisualBasic.Right(Alltext, LN - 2) Do While Alltext <> "" CH2 = Microsoft.VisualBasic.Left(Alltext, 2) If CH2 = vbCrLf Then LN = Microsoft.VisualBasic.Len(Alltext) Alltext = Microsoft.VisualBasic.Right(Alltext, LN - 2) Exit Do End If LN = Microsoft.VisualBasic.Len(Alltext) Alltext = Microsoft.VisualBasic.Right(Alltext, LN - 1) Loop scanComment = " "

  5. 参考(2) ElseIf CH2 = "/*" Then LN = Microsoft.VisualBasic.Len(Alltext) Alltext = Microsoft.VisualBasic.Right(Alltext, LN - 2) Do While Alltext <> "" CH2 = Microsoft.VisualBasic.Left(Alltext, 2) If CH2 = "*/" Then LN = Microsoft.VisualBasic.Len(Alltext) Alltext = Microsoft.VisualBasic.Right(Alltext, LN - 2) Exit Do End If LN = Microsoft.VisualBasic.Len(Alltext) Alltext = Microsoft.VisualBasic.Right(Alltext, LN - 1) Loop scanComment = " " Else scanComment = CH1 LN = Microsoft.VisualBasic.Len(Alltext) Alltext = Microsoft.VisualBasic.Right(Alltext, LN - 1) If CH1 = """" Then ScanMode = 1 ElseIf CH1 = "\" Then ScanMode = 2 End If End If Case 1 scanComment = CH1 LN = Microsoft.VisualBasic.Len(Alltext) Alltext = Microsoft.VisualBasic.Right(Alltext, LN - 1)

  6. 参考(3) If CH1 = """" Then ScanMode = 0 ElseIf CH1 = "\" Then ScanMode = 3 End If Case 2 scanComment = CH1 LN = Microsoft.VisualBasic.Len(Alltext) Alltext = Microsoft.VisualBasic.Right(Alltext, LN - 1) ScanMode = 0 Case 3 scanComment = CH1 LN = Microsoft.VisualBasic.Len(Alltext) Alltext = Microsoft.VisualBasic.Right(Alltext, LN - 1) ScanMode = 1 End Select End Function Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim R, Str As String Alltext = TextBox1.Text Str = "" : ScanMode = 0 Do While Alltext <> "" R = scanComment() TextBox2.Text = TextBox2.Text & R MsgBox(Alltext & vbCrLf & "→[" & R & "] Scan Mode=" & ScanMode) Loop End Sub End Class

  7. (3)単純字句解析 半角・全角空白 またはタブコード 行終り 通常 モード 文字列 内部 引用符(“) 引用符(“) 引用符 直後 文終り エラー 区切記号 状態遷移図 (1文字) 引用符(“) 引用符以外の文字 数字 数字 文終り 数字 モード 小数点 数字 小数点、数字以外 小数部 モード 小数点 数字以外 小数部モードの結果、 得られた文字列が“.”だけの場合、 “.”を区切り記号としてみなす。 英字 英数字 識別子 モード 英数字以外 終了 【演習】C言語を意識した単純字句解析の状態遷移図を書け。 引用符で囲まれたキャラクタ, 二重引用符で囲まれた文字列, \n, \”等の記法を意識すること。

  8. Cの単純字句解析参考(その1) Private Function setWordData(ByVal tp As String, ByVal st As String) As WordData setWordData.Type = tp setWordData.Str = st End Function Private Function setString() Dim Str, R As String Str = """" : R = scanComment() Do While R <> """" If R = "\" Then Str = Str & R : R = scanComment() If R = "" Then MsgBox("文法エラー。二重引用符が不足しています。") R = """" Exit Do End If End If Str = Str & R : R = scanComment() Loop setString = Str & R End Function

  9. Cの単純字句解析参考(その2) Private Function setChar() Dim Str, R As String Str = "'" : R = scanComment() Do While R <> "'" If R = "\" Then Str = Str & R : R = scanComment() If R = "" Then MsgBox("文法エラー。二重引用符が不足しています。") R = "'" Exit Do End If End If Str = Str & R : R = scanComment() Loop setChar = Str & R End Function

  10. Cの単純字句解析参考(その3) Private Function setNumber(ByVal RR As String) Dim Str, R As String : R = RR If R <> "." Then Str = RR : R = scanComment() Do While Asc(R) >= Asc("0") And Asc(R) <= Asc("9") Str = Str & R : R = scanComment() Loop If R <> "." Then Alltext = R & Alltext : setNumber = Str Exit Function End If End If Str = Str & R : R = scanComment() Do While Asc(R) >= Asc("0") And Asc(R) <= Asc("9") Str = Str & R : R = scanComment() Loop Alltext = R & Alltext setNumber = Str End Function

  11. Cの単純字句解析参考(その4) Private Function setName(ByVal RR As String) Dim Str, R As String R = RR : Str = RR : R = scanComment() Do While (Asc(R) >= Asc("A") And Asc(R) <= Asc("Z")) Or _ (Asc(R) >= Asc("a") And Asc(R) <= Asc("z")) Or _ (Asc(R) >= Asc("0") And Asc(R) <= Asc("9")) Or R = "_" Str = Str & R R = scanComment() Loop Alltext = R & Alltext setName = Str End Function

  12. Cの単純字句解析参考(その4) Private Function LA0() As WordData Dim R, Str As String: Str = "" : ScanMode = 0: R = scanComment() Do While Alltext <> "" And (R = " " Or R = "") R = scanComment() Loop If (R = " " Or R = "") And Alltext = "" Then LA0.Type = "EOF”: LA0.Str = "" ElseIf R = """" Then LA0.Type = "String”: LA0.Str = setString() ElseIf R = "'" Then LA0.Type = "Char”: LA0.Str = setChar() ElseIf R = "\" Then LA0.Type = "Code”: LA0.Str = R & scanComment() ElseIf R = "." Then LA0.Type = "Number”: LA0.Str = setNumber(R) If LA0.Str = "." Then LA0.Type = "Delimiter" ElseIf Asc(R) >= Asc("0") And Asc(R) <= Asc("9") Then LA0.Type = "Number”: LA0.Str = setNumber(R) ElseIf (Asc(R) >= Asc("A") And Asc(R) <= Asc("Z")) Or _ (Asc(R) >= Asc("a") And Asc(R) <= Asc("z")) Or R = "_" Then LA0.Type = "Name”: LA0.Str = setName(R) Else LA0.Type = "Delimiter”: LA0.Str = R End If End Function

  13. Cの単純字句解析参考(その5) Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click Dim S As WordData Alltext = TextBox1.Text TextBox2.Text = "" Do While Alltext <> "" S = LA0() TextBox2.Text = TextBox2.Text & vbCrLf & S.Type & " Value=""" & S.Str & """" Loop End Sub End Class

  14. (4)文構成単位としての字句解析 ①浮動小数点等としての「123.5E-23」、「34.E5」等の表現   数値「123.5」、 名前「E」、区切り記号「-」、数値「23」   数値「34.」、 名前「E5」 ②16進数「0X0FEC」等の表現   数値「0」、 名前「X0FEC」 ③8進数「0276」(先頭が0で始まる) ④複数文字列からなる演算子(==, ++, ||など) ⑤2単語以上からなるがひとつの意味になるもの(BASICに多い) select case, end if, do while, loop until, … 先読みしてこれらを判定する

  15. C#プログラム例(その1) private bool E_exp(string str) // E<数字列>のチェック { if(str.Length<2) return false; if(str[0]!='E' && str[0]!='e') return false; for(int i=1;i<str.Length;i++) if(該当文字(数字,str[i])<0) return false; return true; } private void set_TokenX(string type, string str) // トークンのセット { tokenX[numTokenX].type=type; tokenX[numTokenX].str=str; numTokenX++; } private void combineDelimiter(string str1, string str2) // 区切り記号の接続 { set_TokenX("Delimiter",str1+str2); }

  16. C#プログラム例(その2) private void LA1() { numTokenX=0;WordData token1,token2,token3,token4; token1=LA0();token2=LA0();token3=LA0();token4=LA0();// 先読み while(token1.type!="End") { if( token1.type=="Number" && token2.type=="Name" && token2.str=="E" && token3.type=="Delimiter" && (token3.str=="+" || token3.str=="-")&& token4.type=="Number") { set_TokenX("Number",token1.str+token2.str+token3.str+token4.str); token1=LA0();token2=LA0();token3=LA0();token4=LA0(); } else if( token1.type=="Number" && token2.type=="Name" && E_exp(token2.str)) { set_TokenX("Number",token1.str+token2.str); token1=token3;token2=token4;token3=LA0();token4=LA0(); } else if(token1.type=="Delimiter" && token1.str==">" && token2.type=="Delimiter" && token2.str=="=" ) { combineDelimiter(token1.str,token2.str); token1=token3;token2=token4;token3=LA0();token4=LA0(); } else if(token1.type=="Delimiter" && token1.str==”<" && token2.type=="Delimiter" && token2.str=="=" ) { combineDelimiter(token1.str,token2.str); token1=token3;token2=token4;token3=LA0();token4=LA0(); } // 後半省略

  17. (5)1文の形態による字句解析の構成の違い(5)1文の形態による字句解析の構成の違い SA ①行が基本的な文の区切りを示す。 (複数行にわたるときは継続の指定を行う) FORTRAN,BASIC,COBOL 1文取出し LA1 1文バッファ LA0 ②ブロック内の最初と最後を示す記号 (begin-end,{})等があるもの。 ALGOL,PL/I,C,C++,JAVA,C# SA LA1 LA0 1文字取出し

More Related