%skeleton "lalr1.cc" %require "2.4.3" %defines %define parser_class_name "knot_parser" %parse-param { knot_diagram &parsed_knot } // %no-lines %code requires { #include } %code{ #define YY_DECL \ yy::knot_parser::token_type knot_yylex (yy::knot_parser::semantic_type *yylval) YY_DECL; } %union { int integer; bool alternating; basedvector *int_vec; basedvector, 1> *int_vec2; const char *string; } %code { #define yylex knot_yylex } %token INT %token END 0 "end of file" %token PD DT BR LINK X T %token U UNKNOT %token ALT NONALT %token STRING %type alt_spec %type int_vec int_vec_1 %type int_vec2 %type crossing %type crossing_vec %% %start knot; knot: rolfsen_knot | htw_knot | mt_link | planar_diagram | dt | torus_link | unknot | braid ; rolfsen_knot: INT '_' INT { unsigned n = $1, k = $3; if (n >= 1 && n <= 10 && k >= 1 && k <= rolfsen_crossing_knots (n)) parsed_knot = knot_diagram (rolfsen_knot (n, k)); else { fprintf (stderr, "knot_parser: no such Rolfsen knot `%d_%d'\n", n, k); exit (EXIT_FAILURE); } } ; htw_knot: INT alt_spec INT { unsigned n = $1, k = $3; bool alt = $2; if (n >= 1 && n <= 16 && k >= 1 && k <= htw_knots (n, alt)) parsed_knot = knot_diagram (htw_knot (n, alt, k)); else { fprintf (stderr, "knot_parser: no such HTW knot `%d%c%d'\n", n, alt ? 'a' : 'n', k); exit (EXIT_FAILURE); } } ; mt_link: LINK INT alt_spec INT { unsigned n = $2, k = $4; bool alt = $3; if (n >= 1 && n <= 14 && k >= 1 && k <= mt_links (n, alt)) parsed_knot = knot_diagram (mt_link (n, alt, k)); else { fprintf (stderr, "knot_parser: no such MT link `%d%c%d'\n", n, alt ? 'a' : 'n', k); exit (EXIT_FAILURE); } } ; planar_diagram: PD '[' int_vec2 ']' { parsed_knot = knot_diagram (planar_diagram ("", *$3)); } | PD '[' crossing_vec ']' { parsed_knot = knot_diagram (planar_diagram ("", *$3)); } ; dt: DT '[' int_vec_1 ']' { basedvector, 1> even_labels (1); even_labels[1] = *$3; parsed_knot = knot_diagram (dt_code ("", even_labels)); } | DT '[' int_vec2 ']' { parsed_knot = knot_diagram (dt_code ("", *$3)); } | DT '[' STRING ']' { parsed_knot = knot_diagram (dt_code ("", $3)); } ; torus_link: T '(' INT ',' INT ')' { parsed_knot = knot_diagram (torus_knot ($3, $5)); } ; braid: BR '[' INT ',' int_vec ']' { parsed_knot = knot_diagram (braid ($3, *$5)); } ; unknot: UNKNOT { unsigned unknot_ar[1][4] = { { 2, 1, 3, 4, }, }; parsed_knot = knot_diagram ("U", 1, unknot_ar); } ; alt_spec: ALT | NONALT ; int_vec2: int_vec { basedvector, 1> *v = new basedvector, 1> (); v->append (*$1); $$ = v; } | int_vec2 ',' int_vec { basedvector, 1> *v = $1; v->append (*$3); $$ = v; } ; int_vec: '{' int_vec_1 '}' { $$ = $2; } | '[' int_vec_1 ']' { $$ = $2; } ; int_vec_1: INT { basedvector *v = new basedvector (); v->append ($1); $$ = v; } | int_vec_1 ',' INT { basedvector *v = $1; v->append ($3); $$ = v; } ; crossing_vec: crossing { basedvector, 1> *v = new basedvector, 1> (); v->append (*$1); $$ = v; } | crossing_vec ',' crossing { basedvector, 1> *v = $1; v->append (*$3); $$ = v; } ; crossing: X '[' INT ',' INT ',' INT ',' INT ']' { basedvector *v = new basedvector (); v->append ($3); v->append ($5); v->append ($7); v->append ($9); $$ = v; } %% void yy::knot_parser::error (const yy::knot_parser::location_type &l, const std::string &m) { fprintf (stderr, "knot_parser: parse error.\n"); exit (EXIT_FAILURE); } void knot_scan_string (const char *s); knot_diagram parse_knot (const char *s) { knot_scan_string (s); knot_diagram d; yy::knot_parser parser (d); parser.parse (); return d; }