diff -r 000000000000 -r feede61efa96 paper/src/atccl.y --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/src/atccl.y Fri Jun 04 13:48:28 2010 +0200 @@ -0,0 +1,285 @@ +%{ +#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 GATE +%token INTERNAL +%token GLOBAL +%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 DEPTIME +%token ARRTIME +%token GATETIME +%token FL +%type string +%type pttrn +%type flowp +%type constrnt +%type int +%type string_array +%type int_array +%type int_pt +%type time_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); } + | time_pt int_op INTEGER + { time_pt_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; } + | INTERNAL { $$ = PT_INTERNAL; } + | GLOBAL { $$ = PT_GLOBAL; } +; +time_pt: DEPTIME { $$ = PT_DEPTIME; } + | ARRTIME { $$ = PT_ARRTIME; } + | GATETIME { $$ = PT_GATETIME; } +; +char_pt: FTYP { $$ = PT_FTYP; } +; +string_pt: ADEP { $$ = PT_ADEP; } + | ADES { $$ = PT_ADES; } + | RWY { $$ = PT_RWY; } + | ATYP { $$ = PT_ATYP; } + | COPX { $$ = PT_COPX; } + | GATE { $$ = PT_GATE; } + | 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; +}