0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ANTLR4をC#から使ってみる #04 Listenerでの計算機の完成

Posted at

前回の記事までで、下記がわかった。

  • C#でANTLR4を利用するためのVisual Studioの設定方法と、プロジェクトを作った後の設定方法
  • ListenerのではExit***の挙動
  • Exit***リスナーとスタックを使うとListenerで計算機を作れること

実装

Listenerクラスへのスタックの作り込み

Stack<float> stack = new Stack<float>();

演算子(+-*/)の実装

        public override void ExitAddition([NotNull] CalculatorParser.AdditionContext context)
        {
            base.ExitAddition(context);
            stack.Push(stack.Pop() + stack.Pop());
        }
        public override void ExitDivision([NotNull] CalculatorParser.DivisionContext context)
        {
            base.ExitDivision(context);
            var right = stack.Pop();
            var left = stack.Pop();
            stack.Push(left / right);
        }
    ・・・

スタックからの計算結果の取り出し用のメソッド作成

        public float getAnswer()
        {
            return stack.Pop();
        }

mainメソッドからの計算結果の取り出しと出力

            Console.WriteLine(listener.getAnswer());

実行結果

>Calculator01_3.exe 3-1
2

>Calculator01_3.exe 3-1*5
-2

>Calculator01_3.exe 3-1*5/2
0.5

>Calculator01_3.exe (3-1)*5/2
5

>Calculator01_3.exe 1*2+3/4
2.75

最終的なソース

Calculator.g4
grammar Calculator;

PLUS : '+';
MINUS: '-';
MULTI: '*';
DIV  : '/';
NUMBER : [0-9]+;
WHITESPACE : [ \r\n\t]+ -> skip;

expression 
	: NUMBER						# Number
	| '(' expression ')'			# Parentheses
	| expression MULTI expression	# Multiplication
	| expression DIV expression		# Division
	| expression PLUS expression	# Addition
	| expression MINUS expression	# Subtraction
;
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Antlr4.Runtime;

namespace Calculator01_3
{
    class Program
    {
        static void Main(string[] args)
        {
            string parsedString;
            if (args.Length == 0)
            {
                Console.WriteLine("引数に数式を指定してください");
                return;
            }
            else
            {
                parsedString = args[0];

            }
            var inputStream = new AntlrInputStream(parsedString);
            var lexer = new CalculatorLexer(inputStream);
            var commonTokenStream = new CommonTokenStream(lexer);
            var parser = new CalculatorParser(commonTokenStream);

            CalculatorListener listener = new CalculatorListener();
            parser.AddParseListener(listener);
            var graphContext = parser.expression();
            Console.WriteLine(listener.getAnswer());
        }
    }
}
CalculatorListener.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Antlr4.Runtime.Misc;

namespace Calculator01_3
{
    class CalculatorListener : CalculatorBaseListener
    {
        Stack<float> stack = new Stack<float>();
        public override void ExitNumber([NotNull] CalculatorParser.NumberContext context)
        {
            base.ExitNumber(context);
            stack.Push(float.Parse(context.NUMBER().GetText()));
        }
        public override void ExitAddition([NotNull] CalculatorParser.AdditionContext context)
        {
            base.ExitAddition(context);
            stack.Push(stack.Pop() + stack.Pop());
        }
        public override void ExitDivision([NotNull] CalculatorParser.DivisionContext context)
        {
            base.ExitDivision(context);
            var right = stack.Pop();
            var left = stack.Pop();
            stack.Push(left / right);
        }
        public override void ExitMultiplication([NotNull] CalculatorParser.MultiplicationContext context)
        {
            base.ExitMultiplication(context);
            stack.Push(stack.Pop() * stack.Pop());
        }
        public override void ExitSubtraction([NotNull] CalculatorParser.SubtractionContext context)
        {
            base.ExitSubtraction(context);
            var right = stack.Pop();
            var left = stack.Pop();
            stack.Push(left - right);
        }
        public float getAnswer()
        {
            return stack.Pop();
        }
    }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?