帰省したりでかけたりしていて全く進んでいなかったので、ロスタイムとして Yacc をちょこっとやった。ちょこっとやっただけで Yacc で JSON をパースできたので簡単ですごい。 RFC に沿うと、値とかは前後に空白があってもなくてもよいのだけど、それをうまく表現する何かをさっと見つけられなくて、前後の有無で 4パターン書いたりしている。
これを yacc コマンドにかけると y.tab.c という構文解析器のコードが生成されるので、 main.c とかを作って main
関数内で yyparse()
する、という感じでパースできる (Lex ではそれぞれの字句で return L_CBR;
みたいなことをすると Yacc が拾ってくれることになっているっぽい)。構文がおかしいときは素朴に syntax error
とだけ出力され、正しいときは何も出力されない。
%token L_CBR; %token R_CBR; %token L_SBR; %token R_SBR; %token COLON; %token COMMA; %token STRING; %token NUM; %token V_TRUE; %token V_FALSE; %token V_NULL; %token WHITE; %token CHAR; %% text : value | WHITE value | value WHITE | WHITE value WHITE ; begin_array : L_SBR | WHITE L_SBR | L_SBR WHITE | WHITE L_SBR WHITE ; end_array : R_SBR | WHITE R_SBR | R_SBR WHITE | WHITE R_SBR WHITE ; begin_object : L_CBR | WHITE L_CBR | L_CBR WHITE | WHITE L_CBR WHITE ; end_object : R_CBR | WHITE R_CBR | R_CBR WHITE | WHITE R_CBR WHITE ; name_separator : COLON | WHITE COLON | COLON WHITE | WHITE COLON WHITE ; value_separator : COMMA | WHITE COMMA | COMMA WHITE | WHITE COMMA WHITE ; value : V_FALSE | V_NULL | V_TRUE | object | array | NUM | STRING ; object : begin_object end_object | begin_object members end_object ; members : member | members value_separator member ; member : STRING name_separator value ; array : begin_array end_array | begin_array values end_array ; values : value | values value_separator value ;
大学でやったけど完全に風化していた記憶をちゃんと思い出すという点でも、構文解析という知っていて損のない知識をそれなりに学べたという点でも良かった。
完全に自分用でおもてなし皆無だけど、やった内容はこのリポジトリにまとめてある: GitHub - hogashi/sketch-lang-parser: 構文解析の練習