diff -r feede61efa96 -r 866172a16472 book/atccl.y --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/book/atccl.y Wed Mar 23 21:10:10 2011 +0100 @@ -0,0 +1,330 @@ +%{ +#include +#include +#include +#include "semantic_helper.hh" + +#define MAX_ID_TABLE_NO 1024 +char* id_table[MAX_ID_TABLE_NO]; +int id_table_no; + +ErrorType* errors; +int maxErrorNo; +int errorNo; + +int yylex(); +int yywrap(); +int yyerror(const char *str); +void yyrestart(FILE* file); + +%} + +%token +CONSTRNT PATTERN FLOWP COM +QUOTE THAN FROM UNTIL ON + +%union +{ + int integer; + double real; + const char* string; +} + +%token INTEGER +%token TIME +%token REAL +%token STRING + + +%token IS +%token IN +%token GREATER +%token LESS +%token NOT +%token AND +%token OR +%token AT +%token COPX +%token ADEP +%token ADES +%token RWY +%token ROUTE +%token ATYP +%token FLVL +%token TAS +%token FRUL +%token FTYP +%token EQUIP +%token RFL +%token TRAVEL_TYPE +%token TIMESEP +%token FL + +%type string +%type pttrn +%type flowp +%type constrnt +%type int +%type string_array +%type int_array +%type int_pt +%type char_pt +%type string_pt +%type string_array_pt +%type char_array_pt +%type int_op +%type string_op +%type string_array_op +%type string_string_array_op +%type si_unit + +%left OR +%left AND +%right NOT + +%% +prog: | prog rule { } + | error ')' { yyerrok; yyclearin;} +; + +rule: pttrn { if (!pattern($1)) printf("Error: %s\n", last_error()); } + | constrnt { if (!constraint($1)) printf("Error: %s\n", last_error()); } + | flowp { if (!flowpoint($1)) printf("Error: %s\n", last_error()); } + | COM { comment(); } +; + +flowp: FLOWP STRING '(' flowp_entry ')' { $$ = $2; } +; + +flowp_entry: pttrn_lbl ':' constrnt_lbl +; + +pttrn_lbl: STRING { if (!pattern_id($1)) printf("Error: %s\n", last_error()); } +; + +constrnt_lbl: STRING { if (!constraint_id($1)) printf("Error: %s\n", last_error()); } +; + +constrnt: CONSTRNT STRING '(' cterm ')' { $$ = $2; } +; + +cterm: TIMESEP AT string IS INTEGER si_unit + { intpt_string_int_cterm(PT_TIMESEP, $3, $5 * $6, 0, 0, 0); } + | TIMESEP AT string_array IS INTEGER si_unit + { intpt_stringarray_int_cterm(PT_TIMESEP, $3, $5 * $6, 0, 0, 0); } + | TIMESEP AT string IS INTEGER si_unit FROM INTEGER UNTIL INTEGER + { intpt_string_int_cterm(PT_TIMESEP, $3, $5 * $6, $8, $10, 0); } + | TIMESEP AT string_array IS INTEGER si_unit FROM INTEGER UNTIL INTEGER + { intpt_stringarray_int_cterm(PT_TIMESEP, $3, $5 * $6, $8, $10, 0); } + + | TIMESEP AT string IS INTEGER si_unit AT FL int_array + { intpt_string_int_cterm(PT_TIMESEP, $3, $5 * $6, 0, 0, $9); } + | TIMESEP AT string_array IS INTEGER si_unit AT FL int_array + { intpt_stringarray_int_cterm(PT_TIMESEP, $3, $5 * $6, 0, 0, $9); } + | TIMESEP AT string IS INTEGER si_unit FROM INTEGER UNTIL INTEGER AT FL int_array + { intpt_string_int_cterm(PT_TIMESEP, $3, $5 * $6, $8, $10, $13); } + | TIMESEP AT string_array IS INTEGER si_unit FROM INTEGER UNTIL INTEGER AT FL int_array + { intpt_stringarray_int_cterm(PT_TIMESEP, $3, $5 * $6, $8, $10, $13); } + + | cterm AND cterm + { and_term(); } +; + +si_unit: STRING + { + if (!strcmp($1, "s")) { $$ = 1; } + else if (!strcmp($1, "min")) { $$ = 60; } + } +; + +pttrn: PATTERN STRING '(' term ')' { $$ = $2; } + | PATTERN '(' term ')' { $$ = get_pattern_id(); } +; + +term: int_pt int_op INTEGER + { intpt_int_term($2, $1, $3); } + + | char_pt string_op string + { charpt_char_term($2, $1, $3); } + + | string_pt string_op string + { stringpt_string_term($2, $1, $3); } + + | string_array_pt string_array_op string_array + { stringarraypt_stringarray_term($2, $1, $3); } + + | string_array string_array_op string_array_pt + { + if ($2 == OT_IN_C) + { + $2 = OT_IN_P; + } + else if ($2 == OT_NOTIN_C) + { + $2 = OT_NOTIN_P; + } + stringarraypt_stringarray_term($2, $3, $1); + } + + | string string_string_array_op string_array_pt + { + if ($2 == OT_IN_C) + { + $2 = OT_IN_P; + } + else if ($2 == OT_NOTIN_C) + { + $2 = OT_NOTIN_P; + } + stringarraypt_string_term($2, $3, $1); + } + + | string string_string_array_op char_array_pt + { + if ($2 == OT_IN_C) + { + $2 = OT_IN_P; + } + else if ($2 == OT_NOTIN_C) + { + $2 = OT_NOTIN_P; + } + chararraypt_char_term($2, $3, $1); + } + + | term OR term + { or_term(); } + + | term AND term + { and_term(); } + + | NOT term + | '(' term ')' +; + +int_op: IS { $$ = OT_IS; } + | IS NOT { $$ = OT_ISNOT; } + | GREATER THAN { $$ = OT_GREATER; } + | LESS THAN { $$ = OT_LESS; } +; + +string_op: IS { $$ = OT_IS; } + | IS NOT { $$ = OT_ISNOT; } +; + +string_array_op:IS { $$ = OT_IS; } + | IS NOT { $$ = OT_ISNOT; } + | IN { $$ = OT_IN_P; } + | NOT IN { $$ = OT_NOTIN_P; } +; + +string_string_array_op: IN { $$ = OT_IN_P; } + | NOT IN { $$ = OT_NOTIN_P; } +; + +int_array: '[' ints ']' { $$ = integer_array(); } +; + +ints: | ints ',' int + | ints int +; + +int: INTEGER { integer($1); $$ = $1; } +; + +string_array: '[' strings ']' { $$ = string_array(); } +; + +strings: | strings ',' string + | strings string +; + +int_pt: TAS { $$ = PT_TAS; } +; + +char_pt: FTYP { $$ = PT_FTYP; } + +string_pt: ADEP { $$ = PT_ADEP; } + | ADES { $$ = PT_ADES; } + | RWY { $$ = PT_RWY; } + | ATYP { $$ = PT_ATYP; } + | COPX { $$ = PT_COPX; } + | FRUL { $$ = PT_FRUL; } + | RFL { $$ = PT_RFL; } + | TRAVEL_TYPE { $$ = PT_TRAVEL_TYPE; } +; + +string_array_pt:ROUTE { $$ = PT_ROUTE; } +; + +char_array_pt: EQUIP { $$ = PT_EQUIP; } +; + +string: QUOTE STRING QUOTE { string($2); $$ = $2; } +; +%% + +#include "atccl_parser.c" + +void clear_id_table() +{ + int i; + for (i = 0; i < id_table_no; ++i) + { + free(id_table[i]); + id_table[i] = 0; + } + id_table_no = 0; +} + +int yywrap() +{ + clear_id_table(); + return 1; +} + +int semantic_error(const char* str) +{ + if (errorNo < maxErrorNo) + { + errors[errorNo].line = -1; + strcpy(errors[errorNo].text, ""); + strcpy(errors[errorNo].error, str); + errorNo++; + } + return 1; +} + +int yyerror(const char *str) +{ + if (errorNo < maxErrorNo) + { + errors[errorNo].line = line_no; + strcpy(errors[errorNo].text, yytext); + strcpy(errors[errorNo].error, str); + errorNo++; + } + return 1; +} + +int parse_syntax(FILE* file, ErrorType* errors_, int maxErrorNo_, int passes) +{ + line_no = 1; + errors = errors_; + maxErrorNo = maxErrorNo_; + errorNo = 0; + + clear_all(); + clear_id_table(); + yyrestart(file); + yyparse(); + + if (passes > 1) + { + if (!complete_semantics()) + { + semantic_error(last_error()); + } + } + return errorNo; +}