|
■No6249 (韋駄天 さん) に返信
> VB.NETで電卓を作りました。
> 普通の1回の四則演算までは出来ました。
> ただ、1+2+3だとか1+3−4
> のような連続した計算の仕方がわかりません。
どえりやー長いけど、
TextBox1,TextBox2,Button1,Button2 4つ用意してコピペしてGO。
正負符号と掛け算・割り算が抜けています。アクアさんのHPは見たことありませんが、
これとはまったく異なるやり方で実装されているかもしれません。
以下の処理に、代入とか複合代入とか、単項演算子とか、if 文とか function とか、
加えて拡張していくと、簡単なマクロ言語が出来ます。で、出来合いの文法通りに実装
すると C# や VB.NET が出来ます。
Parse1() と Parse2() が互いに呼び合うのは理解しにくいかもしれませんが、m_var に
格納される種別コードを1つずつ順に追っていくとうっすらとなにやっているのかが
理解できそうなできなさそうな、頭がこんがらがってきそうで・・・・な感じです。
"後置記法"をWiki で下調べした上で見てみるとGoodですね。
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
Private Sub ClearText()
TextBox1.Text = ""
TextBox2.Text = ""
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
ClearText()
End Sub
Private Class ParseException
Inherits Exception
Public Sub New()
MyBase.New("Parse Error")
End Sub
Public Sub New(ByVal s As String)
MyBase.New(s)
End Sub
End Class
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Init()
GetChar()
Dim answer As Var = Parse1()
TextBox2.Text = CStr(answer.Value)
End Sub
Private Function Parse1() As Var
Dim leftVal As Var = Parse2()
Do While m_var.Code = CharType.C_ADD Or m_var.Code = CharType.C_SUB
If m_var.Code = CharType.C_ADD Then
GetChar()
Dim rightVal As Var = Parse2()
leftVal.Value = DirectCast(leftVal.Value, Integer) + DirectCast(rightVal.Value, Integer)
Else
GetChar()
Dim rightVal As Var = Parse2()
leftVal.Value = DirectCast(leftVal.Value, Integer) - DirectCast(rightVal.Value, Integer)
End If
Loop
Return leftVal
End Function
Private Function Parse2() As Var
If m_var.Code = CharType.C_LPAR Then
GetChar()
Dim val As Var = Parse1()
If m_var.Code <> CharType.C_RPAR Then
Throw New ParseException(") expected")
Else
GetChar()
Return val
End If
Else
Dim val As Var = m_var.Clone()
GetChar()
Return val
End If
End Function
Private Structure Var
Private m_cod As CharType
Private m_val As Object
Public Property Code() As CharType
Get
Return m_cod
End Get
Set(ByVal value As CharType)
m_cod = value
End Set
End Property
Public Property Value() As Object
Get
Return m_val
End Get
Set(ByVal value As Object)
m_val = value
End Set
End Property
Public Sub New(ByVal cod As CharType)
m_cod = cod
m_val = Nothing
End Sub
Public Sub New(ByVal cod As CharType, ByVal val As Object)
m_cod = cod
m_val = val
End Sub
Public Function Clone() As Var
Return New Var(m_cod, m_val)
End Function
End Structure
Private Enum CharType
C_ADD
C_SUB
C_LPAR
C_RPAR
C_NUM
C_EOS
C_UNK
End Enum
Private m_pos As Integer = 0
Private m_str As String
Private m_lst As ArrayList
Private m_var As New Var
Private Sub Init()
m_pos = 0
m_str = TextBox1.Text
m_lst = New ArrayList()
m_lst.Add(New Var(CharType.C_UNK, "???"))
End Sub
Private Sub GetChar()
m_var.Code = CharType.C_EOS
Do While m_pos < m_str.Length
Dim ch As Char = m_str.Chars(m_pos)
Dim sNum As String = ""
If ch >= "0" And ch <= "9" Then
Try
Do While ch >= "0" And ch <= "9"
sNum = sNum + ch
m_pos = m_pos + 1
ch = m_str.Chars(m_pos) ''IndexOutOfBoundsException
Loop
Catch ex As Exception
''この例外は無視してOKよん
End Try
m_var.Value = CInt(sNum)
m_var.Code = CharType.C_NUM
Exit Sub
End If
If ch = "+" Then
m_pos = m_pos + 1
m_var.Code = CharType.C_ADD
Exit Sub
End If
If ch = "-" Then
m_pos = m_pos + 1
m_var.Code = CharType.C_SUB
Exit Sub
End If
If ch = "(" Then
m_pos = m_pos + 1
m_var.Code = CharType.C_LPAR
Exit Sub
End If
If ch = ")" Then
m_pos = m_pos + 1
m_var.Code = CharType.C_RPAR
Exit Sub
End If
If ch <> " " Then
Throw New NotSupportedException(ch + " is not supported.")
End If
m_pos = m_pos + 1
Loop
End Sub
End Class
|