3.2 字句解析のプログラム
This presentation is the property of its rightful owner.
Sponsored Links
1 / 17

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


  • 64 Views
  • Uploaded on
  • Presentation posted in: General

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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


7094582

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

1文読込み

(注釈部分の削除)

ソースプログラム

1文(テキスト

数値/文字列/

名前/区切り記号

単純字句解析

12.3,E,-15, 12.3,E5,+,=, >,<,…,

while, if,・・・,”abcdefg”

文構成単位の

字句解析

トークン

ソース

プログラム

ファイル

エディタ用

テキスト

ボックス

12.3E-15, 12.3E5

==,++,+=, >=, … ,

while, if,・・・,

“abcdefg”

構文解析


7094582

(2)1文読込み(注釈部分の削除)

VBに似た言語の1文読込み

①1行に1文が基本。

②1行に複文のときコロン(:)で区切る

③複数行にまたがるときはアンダーライン(_)を最後に付ける。

④注釈の先頭はシングルクォート(‘)


7094582

1文読込みの状態遷移

行終り

通常

モード

文字列内部

引用符(“)

引用符(“)

引用符直後

行終り

エラー

状態遷移図

引用符(“)

引用符以外の文字

継続指定“ _”

行終りまで無視(継続行用)

行終り以外

行終り

行終り以外

行終りまで無視(注釈用)

注釈指定“‘”

行終り

行終り

“:”または行終り

終了

【演習】C言語の1文読み込みの状態遷移図を書け。

①8進数はないものとする。

②\n,\”等の記法が許されるものとする。


7094582

参考(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 = " "


7094582

参考(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)


7094582

参考(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


7094582

(3)単純字句解析

半角・全角空白

またはタブコード

行終り

通常

モード

文字列

内部

引用符(“)

引用符(“)

引用符

直後

文終り

エラー

区切記号

状態遷移図

(1文字)

引用符(“)

引用符以外の文字

数字

数字

文終り

数字

モード

小数点

数字

小数点、数字以外

小数部

モード

小数点

数字以外

小数部モードの結果、

得られた文字列が“.”だけの場合、

“.”を区切り記号としてみなす。

英字

英数字

識別子

モード

英数字以外

終了

【演習】C言語を意識した単純字句解析の状態遷移図を書け。

引用符で囲まれたキャラクタ, 二重引用符で囲まれた文字列, \n, \”等の記法を意識すること。


7094582

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


7094582

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


7094582

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


7094582

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


7094582

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


7094582

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


7094582

(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, …

先読みしてこれらを判定する


7094582

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);

}


7094582

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();

} // 後半省略


7094582

(5)1文の形態による字句解析の構成の違い

SA

①行が基本的な文の区切りを示す。

(複数行にわたるときは継続の指定を行う)

FORTRAN,BASIC,COBOL

1文取出し

LA1

1文バッファ

LA0

②ブロック内の最初と最後を示す記号

(begin-end,{})等があるもの。

ALGOL,PL/I,C,C++,JAVA,C#

SA

LA1

LA0

1文字取出し


  • Login