Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9749

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

$
0
0

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

  • 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
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingAntlr4.Runtime;namespaceCalculator01_3{classProgram{staticvoidMain(string[]args){stringparsedString;if(args.Length==0){Console.WriteLine("引数に数式を指定してください");return;}else{parsedString=args[0];}varinputStream=newAntlrInputStream(parsedString);varlexer=newCalculatorLexer(inputStream);varcommonTokenStream=newCommonTokenStream(lexer);varparser=newCalculatorParser(commonTokenStream);CalculatorListenerlistener=newCalculatorListener();parser.AddParseListener(listener);vargraphContext=parser.expression();Console.WriteLine(listener.getAnswer());}}}
CalculatorListener.cs
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingAntlr4.Runtime.Misc;namespaceCalculator01_3{classCalculatorListener:CalculatorBaseListener{Stack<float>stack=newStack<float>();publicoverridevoidExitNumber([NotNull]CalculatorParser.NumberContextcontext){base.ExitNumber(context);stack.Push(float.Parse(context.NUMBER().GetText()));}publicoverridevoidExitAddition([NotNull]CalculatorParser.AdditionContextcontext){base.ExitAddition(context);stack.Push(stack.Pop()+stack.Pop());}publicoverridevoidExitDivision([NotNull]CalculatorParser.DivisionContextcontext){base.ExitDivision(context);varright=stack.Pop();varleft=stack.Pop();stack.Push(left/right);}publicoverridevoidExitMultiplication([NotNull]CalculatorParser.MultiplicationContextcontext){base.ExitMultiplication(context);stack.Push(stack.Pop()*stack.Pop());}publicoverridevoidExitSubtraction([NotNull]CalculatorParser.SubtractionContextcontext){base.ExitSubtraction(context);varright=stack.Pop();varleft=stack.Pop();stack.Push(left-right);}publicfloatgetAnswer(){returnstack.Pop();}}}

Viewing all articles
Browse latest Browse all 9749

Trending Articles