構文解析もどき

kansuke3
記事: 1
登録日時: 5年前

構文解析もどき

投稿記事 by kansuke3 » 4年前

暇だったので、学習用に数式の構文解析をつくってみました。
一応、再帰降下構文解析みたいなものです。
例外の部分はおそらくいらないです。
出力時の整形はきたないです。

CODE:

#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;

void num(const string& s,int& index,int tab){
    int num=0;
    if(!(((s[index]>='0')&&(s[index]<='9'))&&(index<static_cast<int>(s.length())))){throw index;}
    while(((s[index]>='0')&&(s[index]<='9'))&&(index<static_cast<int>(s.length()))){num=num*10+s[index]-'0';index++;}
    for(int i=0;i<tab;i++)cout<<"\t";
    cout<<"NUM: "<<num<<"\n";
}

void term(const string& s,int& index,int tab){
    for(int i=0;i<tab;i++)cout<<"\t";
    cout<<"TERM:(\n";
    num(s,index,tab+1);
    if((s[index]=='*'||s[index]=='/')&&(index<static_cast<int>(s.length()))){
        for(int i=0;i<tab+1;i++)cout<<"\t";
        cout<<"OPERATOR: "<<s[index]<<"\n";
        index++;
        term(s,index,tab+1);
    }
    for(int i=0;i<tab;i++)cout<<"\t";
    cout<<")\n";
}

void expr(const string& s){
    int index=0;
    try{
        cout<<"EXPR:(\n";
        term(s,index,1);
        while((s[index]=='+'||s[index]=='-')&&(index<static_cast<int>(s.length()))){
            cout<<"\t"<<"OPERATOR: "<<s[index]<<"\n";
            index++;
            term(s,index,1);
        }
        cout<<")";
    }catch(const int& c){
        cout<<"\n"<<s<<"\n"<<index+1<<":不正な文字>>\" "<<s[index]<<" \"\n";
        exit(1);
    }
}

int main(void){
    string s;
    cin>>s;
    expr(s);
    return 0;
}

結果
入力
2-4*5-2/3*1
出力

CODE:

EXPR:(
        TERM:(
                NUM: 2
        )
        OPERATOR: -
        TERM:(
                NUM: 4
                OPERATOR: *
                TERM:(
                        NUM: 5
                )
        )
        OPERATOR: -
        TERM:(
                NUM: 2
                OPERATOR: /
                TERM:(
                        NUM: 3
                        OPERATOR: *
                        TERM:(
                                NUM: 1
                        )
                )
        )
)
改善点
  • 括弧に対応する。
  • eval関数をつくる。
これからは、もっとさきのフェーズにも手をだしたいですが、
知識がほとんどないので書籍を購入して学習しようとおもいます。

github https://github.com/kansuke3/expr_paser
最後に編集したユーザー kansuke3 on 2020年8月30日(日) 23:25 [ 編集 1 回目 ]

コメントはまだありません。