数式を構文解析した話

20
(・ω・`) Knct-SG #2 @y1r96

Upload: y1r96-ueno

Post on 05-Aug-2015

230 views

Category:

Technology


4 download

TRANSCRIPT

(́・ω・`)Knct-SG #2 @y1r96

parser 入門 ~使ってみようlibxml2~

Knct-SG #1 @y1r96

2

進捗はありません

3

ゆるして♥

4

5

parser, 作ろう.

6

でんたくつくります

7

ソースコード

8

calc.py

• #!/usr/bin/env python# -*- coding: utf-8 -*-exp = raw_input( “input:” )print "ans:" + str(eval( exp ))

9

10

まじめにつくります

11

#include <iostream> #include <string> #include <cstdlib> using namespace std; !double calc( string exp ); int main( void ){ string exp; ! cin >> exp; ! cout << calc( exp ); ! return 0; } double calc( string exp ){ int mulPos; int divPos; ! mulPos = exp.find( '*' ); divPos = exp.find( '/' ); if( mulPos == string::npos && divPos == string::npos ){ int addPos; int subPos; addPos = exp.find( '+' ); subPos = exp.find( '-' ); if( addPos == string::npos && subPos == string::npos ) return atof( exp.c_str() ); if( addPos == string::npos && subPos != string::npos ) return calc( exp.substr( 0, subPos ) ) - calc( exp.substr( subPos + 1 ) ); if( addPos != string::npos && subPos == string::npos ) return calc( exp.substr( 0, addPos ) ) + calc( exp.substr( addPos + 1 ) ); if( addPos != string::npos && subPos != string::npos ){ if( addPos < subPos ) return calc( exp.substr( 0, addPos ) ) + calc( exp.substr( addPos + 1 ) ); else return calc( exp.substr( 0, subPos ) ) - calc( exp.substr( subPos + 1 ) ); } } if( mulPos == string::npos && divPos != string::npos ) return calc( exp.substr( 0, divPos ) ) / calc( exp.substr( divPos + 1 ) ); if( mulPos != string::npos && divPos == string::npos ) return calc( exp.substr( 0, mulPos ) ) * calc( exp.substr( mulPos + 1 ) ); ! if( mulPos != string::npos && divPos != string::npos ){ if( mulPos < divPos ) return calc( exp.substr( 0, mulPos ) ) * calc( exp.substr( mulPos + 1 ) ); else return calc( exp.substr( 0, divPos ) ) / calc( exp.substr( divPos + 1 ) ); } } 12

うごかしてみよう• ➜ calc git:(master) ✗ ./a.out ./a.out3+25 ➜ calc git:(master) ✗ ./a.out 3+2+16 ➜ calc git:(master) ✗ ./a.out 2*24 ➜ calc git:(master) ✗ ./a.out 2*3/32 ➜ calc git:(master) ✗ ./a.out 1+2*39 ???????????????

13

#include <iostream> #include <string> #include <cstdlib> using namespace std; !double calc( string exp ); int main( void ){ string exp; ! cin >> exp; ! cout << calc( exp ); ! return 0; } double calc( string exp ){ int mulPos; int divPos; ! mulPos = exp.find( '*' ); divPos = exp.find( '/' ); if( mulPos == string::npos && divPos == string::npos ){ int addPos; int subPos; addPos = exp.find( '+' ); subPos = exp.find( '-' ); if( addPos == string::npos && subPos == string::npos ) return atof( exp.c_str() ); if( addPos == string::npos && subPos != string::npos ) return calc( exp.substr( 0, subPos ) ) - calc( exp.substr( subPos + 1 ) ); if( addPos != string::npos && subPos == string::npos ) return calc( exp.substr( 0, addPos ) ) + calc( exp.substr( addPos + 1 ) ); if( addPos != string::npos && subPos != string::npos ){ if( addPos < subPos ) return calc( exp.substr( 0, addPos ) ) + calc( exp.substr( addPos + 1 ) ); else return calc( exp.substr( 0, subPos ) ) - calc( exp.substr( subPos + 1 ) ); } } if( mulPos == string::npos && divPos != string::npos ) return calc( exp.substr( 0, divPos ) ) / calc( exp.substr( divPos + 1 ) ); if( mulPos != string::npos && divPos == string::npos ) return calc( exp.substr( 0, mulPos ) ) * calc( exp.substr( mulPos + 1 ) ); ! if( mulPos != string::npos && divPos != string::npos ){ if( mulPos < divPos ) return calc( exp.substr( 0, mulPos ) ) * calc( exp.substr( mulPos + 1 ) ); else return calc( exp.substr( 0, divPos ) ) / calc( exp.substr( divPos + 1 ) ); } } 14

私が実装した演算規則

• hoge+foo-bar = hoge + calc( foo - bar )= hoge + foo - bar // 動作かくにん! よかった

• hoge*foo/bar = hoge * calc( foo / bar )= hoge * foo / bar // 動作かくにん! よかった

15

私が実装した演算規則

• hoge*foo+bar = hoge * calc( foo + bar )= hoge * (foo+bar) // おかしい

16

#include <iostream> #include <string> #include <cstdlib> using namespace std; !double calc( string exp ); int main( void ){ string exp; ! cin >> exp; ! cout << calc( exp ); ! return 0; } double calc( string exp ){ int addPos; int subPos; ! addPos = exp.find( '+' ); subPos = exp.find( '-' ); if( addPos == string::npos && subPos == string::npos ){ int mulPos; int divPos; mulPos = exp.find( '*' ); divPos = exp.find( '/' ); if( mulPos == string::npos && divPos == string::npos ) return atof( exp.c_str() ); if( mulPos == string::npos && divPos != string::npos ) return calc( exp.substr( 0, divPos ) ) / calc( exp.substr( divPos + 1 ) ); if( mulPos != string::npos && divPos == string::npos ) return calc( exp.substr( 0, mulPos ) ) * calc( exp.substr( mulPos + 1 ) ); if( mulPos != string::npos && divPos != string::npos ){ if( mulPos < divPos ) return calc( exp.substr( 0, mulPos ) ) * calc( exp.substr( mulPos + 1 ) ); else return calc( exp.substr( 0, divPos ) ) / calc( exp.substr( divPos + 1 ) ); } } if( addPos == string::npos && subPos != string::npos ) return calc( exp.substr( 0, subPos ) ) - calc( exp.substr( subPos + 1 ) ); if( addPos != string::npos && subPos == string::npos ) return calc( exp.substr( 0, addPos ) ) + calc( exp.substr( addPos + 1 ) ); ! if( addPos != string::npos && subPos != string::npos ){ if( addPos < subPos ) return calc( exp.substr( 0, addPos ) ) + calc( exp.substr( addPos + 1 ) ); else return calc( exp.substr( 0, subPos ) ) - calc( exp.substr( subPos + 1 ) ); } !} 17

うごかしてみよう• ➜ calc git:(master) ✗ ./a.out ./a.out3+25 ➜ calc git:(master) ✗ ./a.out 3+2+16 ➜ calc git:(master) ✗ ./a.out 2*24 ➜ calc git:(master) ✗ ./a.out 2*3/32 ➜ calc git:(master) ✗ ./a.out 1+2*37 // 動作かくにん!よかった

18

動きの流れ

• Input: a+b*c+d = calc(a) + calc( b*c + d ) // +で分割= a + calc( b*c ) + calc( d ) // +で分割 & atof= a + calc(b) * calc(c) + d // atof & *で分割= a + b * c + d // atof

おわり()