//**************************************************************** //* * //* Syntax.y : Grammar for the LOGLAN-82 and the LOGLAN-93 * //* languages. * //* * //* (c) LITA, university of PAU (France), summer 1993. * //**************************************************************** %{ #ifdef RULES_DEBUG #define RULES_DEBUG_printf(a) fprintf(stderr,a) #define RULES_ERROR_DEBUG #else #define RULES_DEBUG_printf(a) #endif #ifdef RULES_ERROR_DEBUG #define RULES_ERROR_printf(a) fprintf(stderr,a) #else #define RULES_ERROR_printf(a) #endif #ifndef SYNTAX_ONLY #define SEMANTIC(a) a #include #include #include #include "Objects.h" #include "Expr.h" #include "Instr.h" extern int BeginningOfLine; #else #define SEMANTIC(a) #endif void initialize( void ); int yylex( void ); int line_number; int yyerror( void ); int yyerror( char * ); %} %union { Expression *Expr; Instruction *Instr; Block *ThisBlock; Location *ThisLoc; BoolOpType bool; ArithOpType arith; ObjOpType object; OneArgJob ThisArgJob; LocInt ThisInt; LocDouble ThisReal; LocChar ThisChar; LocStr ThisString; LocBool ThisBool; } %type binary_operator %type arith_operator arith_operator2 %type opt_Num_const %type opt_prefix_sign %type factor expression expression_in_bracket %type NumberConst object_factor composed_expr2 %type composed_expr logic_expr variable %type object generator r_value %type one_or_more_logic_factor one_or_more_logic_term %type one_or_more_factor one_or_more_term %type non_prefixed_variable non_prefixed_generator %type short_or_and_list %type object_operator %type affectation_instruction instruction %type single_instruction complex_instruction %type condition_instruction loop_instruction %type parameter_job_instruction %type instructions opt_instructions opt_else loop_body // Main %token PROGRAM BLOCK PREF // Module definition %token UNIT CLASS PROCEDURE FUNCTION %token COROUTINE PROCESS VIRTUAL SHARED ENUM // Parameters transmission mode %token INPUT OUTPUT INOUT TAKEN CLOSE HIDDEN // Sub-parts of module %token HANDLERS SIGNAL Begin END // Variable and constants declarations %token VAR CONST %token IDENTIFIER %token INTEGER TYPE REAL BOOLEAN CHARACTER %token STRING File ARRAY //Punctuation %token LIST_SEPARATOR VARSEPARATOR OPENINGBRACKET %token CLOSINGBRACKET ENDSENTENCE POINT //Operators %token STAR DIVIDE DIV MOD PLUS MINUS %token LESS LESSOREQUAL EQUAL NEQUAL %token GREATER GREATEROREQUAL %token OR AND NOT ANDIF ORIF %token AFFECTATION %token QUA THIS IS IN NEW COPY ARRAY_OF %token NONE // Constants %token TEXTCONST %token CHARCONST %token DIGITSEQUENCE %token BOOLCONST //Keywords for Instructions %token IF THEN ELSE FI %token CASE WHEN OTHERWISE ESAC %token WHILE FOR STEP TO DOWNTO DO OD %token ATTACH DETACH RESUME STOP TERMINATE %token RESULT %token GET PUT READ READLN WRITE WRITELN %token DIM %token RAISE KILL %token CALL RETURN %token EXIT REPEAT %token INNER WIND %% // We begin with the main rule that initialize the variables analyse the // program and then go on is compilation. but: initloglan program endprogram analyse { RULES_DEBUG_printf(" but -> initloglan program analyse \n");} ; // This rule is empty. Is only use is for side-effect. initloglan: { initialize(); } ; // This one too... analyse: ; program: program_module {RULES_DEBUG_printf("program -> program_module.\n"); } | block_module {RULES_DEBUG_printf("program -> block_module.\n"); } | unit_module {RULES_DEBUG_printf("program -> unit_module.\n"); } ; program_module: PROGRAM IDENTIFIER endsentence module_body { RULES_DEBUG_printf("program_module -> PROGRAM IDENTIFIER endsentence module_body.\n"); } | PROGRAM error module_body { RULES_ERROR_printf(" error: program name missing.\n"); } ; block_module: BLOCK module_body { RULES_DEBUG_printf("block_module -> BLOCK module_body.\n"); } | error { RULES_ERROR_printf(" error : BLOCK or PROGRAM expected.\n"); } ; unit_module: module_header module_body { RULES_DEBUG_printf("unit_module -> module_header module_body.\n"); } ; module_body: opt_declarations module_code { RULES_DEBUG_printf("module_body -> opt_declarations module_code.\n"); } ; module_header: UNIT opt_virtual IDENTIFIER VARSEPARATOR prefix_list module_type parameters endsentence opt_visibility_declarations { RULES_DEBUG_printf("module_header -> UNIT opt_virtual IDENTIFIER VARSEPARATOR prefix_list modul_type parameters endsentence opt_visibility_declarations.\n"); } | UNIT opt_virtual IDENTIFIER VARSEPARATOR ENUM OPENINGBRACKET identifier_list CLOSINGBRACKET endsentence { RULES_DEBUG_printf("module_header -> UNIT opt_virtual IDENTIFIER VARSEPARATOR ENUM OPENINGBRACKET identifier_list CLOSINGBRACKET endsentence.\n"); } ; prefix_list: { RULES_DEBUG_printf("prefix_list -> .\n"); } | list_prefix { RULES_DEBUG_printf("prefix_list -> list_prefix.\n"); }; list_prefix: opt_shared identifier_path { RULES_DEBUG_printf("list_prefix -> identifier_path .\n"); } | opt_shared identifier_path LIST_SEPARATOR prefix_list { RULES_DEBUG_printf("list_prefix -> identifier_path LIST_SEPARATOR prefix_list.\n"); } ; opt_shared: SHARED { RULES_DEBUG_printf("opt_shared -> SHARED.\n"); } | { RULES_DEBUG_printf("opt_shared -> .\n"); } ; opt_virtual: VIRTUAL { RULES_DEBUG_printf("opt_virtual -> VIRTUAL.\n"); } | { RULES_DEBUG_printf("opt_virtual -> .\n"); } ; identifier_path: IDENTIFIER { RULES_DEBUG_printf("identifier_path -> IDENTIFIER.\n"); } | IDENTIFIER VARSEPARATOR identifier_path { RULES_DEBUG_printf("identifier_path -> IDENTIFIER VARSEPARATOR identifier_path.\n"); } ; module_type: CLASS { RULES_DEBUG_printf("module_type -> CLASS.\n"); } | PROCEDURE { RULES_DEBUG_printf("module_type -> PROCEDURE.\n"); } | FUNCTION { RULES_DEBUG_printf("module_type -> FUNCTION.\n"); } | COROUTINE { RULES_DEBUG_printf("module_type -> COROUTINE.\n"); } | PROCESS { RULES_DEBUG_printf("module_type -> PROCESS.\n"); } ; parameters: OPENINGBRACKET formal_parameters_list opt_endsentence CLOSINGBRACKET end_parameters { RULES_DEBUG_printf("parameters -> OPENINGBRACKET formal_parameters_list opt_endsentence CLOSINGBRACKET end_parameters.\n"); } | end_parameters { RULES_DEBUG_printf("parameters -> end_parameters.\n"); } ; end_parameters: VARSEPARATOR typeident { RULES_DEBUG_printf("end_parameters -> VARSEPARATOR IDENTIFIER.\n"); } | { RULES_DEBUG_printf("end_parameters -> .\n"); } ; formal_parameters_list: formal_parameters_list endsentence formal_parameter { RULES_DEBUG_printf("formal_parameters_list -> formal_parameters_list endsentence formal_parameter.\n"); } | formal_parameter { RULES_DEBUG_printf("formal_parameters_list -> formal_parameter.\n"); } ; formal_parameter: parametertype var_param_list { RULES_DEBUG_printf("formal_parameter -> parametertype var_param_list.\n"); } | TYPE IDENTIFIER { RULES_DEBUG_printf("formal_parameter -> TYPE IDENTIFIER.\n"); } | callable_module { RULES_DEBUG_printf("formal_parameter -> callable_module.\n"); } ; parametertype: INPUT { RULES_DEBUG_printf("parametertype -> INPUT.\n"); } | OUTPUT { RULES_DEBUG_printf("parametertype -> OUTPUT.\n"); } | INOUT { RULES_DEBUG_printf("parametertype -> INOUT.\n"); } | { RULES_DEBUG_printf("parametertype -> .\n"); } ; var_param_list: var_param_list LIST_SEPARATOR var_declaration { RULES_DEBUG_printf("var_param_list -> var_param_list LIST_SEPARATOR var_declaration.\n"); } | var_declaration { RULES_DEBUG_printf("var_param_list -> var_declaration.\n"); } ; var_declaration: identifier_list VARSEPARATOR typeident { RULES_DEBUG_printf("var_declaration -> identifier_list VARSEPARATOR typeident.\n"); } ; identifier_list: identifier_list LIST_SEPARATOR IDENTIFIER { RULES_DEBUG_printf("identifier_list -> identifier_list LIST_SEPARATOR IDENTIFIER.\n"); } | IDENTIFIER { RULES_DEBUG_printf("identifier_list -> IDENTIFIER.\n"); } ; typeident: list_arrayof definedtype { RULES_DEBUG_printf(" typeident -> list_arrayof definedtype .\n"); } | definedtype { RULES_DEBUG_printf(" typeident -> definedtype .\n"); } ; list_arrayof: list_arrayof ARRAY_OF { RULES_DEBUG_printf(" list_arrayof -> list_arrayof ARRAY_OF .\n"); } | ARRAY_OF { RULES_DEBUG_printf(" list_arrayof -> .\n"); } ; definedtype: predefinedtype | IDENTIFIER ; predefinedtype: INTEGER { RULES_DEBUG_printf(" predefinedtype -> INTEGER .\n"); } | REAL { RULES_DEBUG_printf(" predefinedtype -> REAL.\n"); } | BOOLEAN { RULES_DEBUG_printf(" predefinedtype -> BOOLEAN.\n"); } | CHARACTER { RULES_DEBUG_printf(" predefinedtype -> CHARACTER.\n"); } | STRING { RULES_DEBUG_printf(" predefinedtype -> STRING.\n"); } | File { RULES_DEBUG_printf(" predefinedtype -> FILE.\n"); } | PROCESS { RULES_DEBUG_printf(" predefinedtype -> PROCESS.\n"); } | COROUTINE { RULES_DEBUG_printf(" predefinedtype -> PROCESS.\n"); } ; callable_module: function_callable { RULES_DEBUG_printf("callable_module -> function_callable.\n"); } | procedure_callable { RULES_DEBUG_printf("callable_module -> procedure_callable.\n"); } ; function_callable: FUNCTION IDENTIFIER parameters { RULES_DEBUG_printf("function_callable -> FUNCTION IDENTIFIER parameters.\n"); } ; procedure_callable: PROCEDURE IDENTIFIER parameters { RULES_DEBUG_printf("procedure_callable -> PROCEDURE IDENTIFIER parameters.\n"); } ; handlers_declaration: HANDLERS handlers_body END HANDLERS opt_endsentence { RULES_DEBUG_printf("handlers_declaration -> HANDLERS handlers_body END HANDLERS opt_endsentence.\n"); } ; opt_endsentence: ENDSENTENCE { RULES_DEBUG_printf("opt_endsentence -> ENDSENTENCE.\n"); } | { RULES_DEBUG_printf("opt_endsentence -> .\n"); } ; endsentence: ENDSENTENCE { RULES_DEBUG_printf("endsentence -> ENDSENTENCE.\n"); } | error { RULES_ERROR_printf("error : ';' expected.\n"); } handlers_body: when_list opt_others { RULES_DEBUG_printf("handlers_body -> when_list opt_others.\n"); } ; when_list: when_list when_unique { RULES_DEBUG_printf("when_list -> when_list when_unique.\n"); } | when_unique { RULES_DEBUG_printf("when_list -> when_unique.\n"); } ; when_unique: WHEN identifier_list VARSEPARATOR instructions { RULES_DEBUG_printf("when_unique -> WHEN identifier_list VARSEPARATOR instructions.\n"); } ; opt_others: OTHERWISE VARSEPARATOR instructions { RULES_DEBUG_printf("opt_others -> OTHERWISE VARSEPARATOR instructions.\n"); } | { RULES_DEBUG_printf("opt_others -> .\n"); } ; module_code: Begin opt_instructions END module_code_end { RULES_DEBUG_printf("module_code -> BEGIN opt_instructions END module_code_end.\n"); SEMANTIC( { if ($2) $2->Print( cout ); }); } | END module_code_end { RULES_DEBUG_printf("module_code -> END module_code_end.\n"); } ; opt_instructions: instructions { RULES_DEBUG_printf("opt_instructions -> instructions opt_endsentence.\n"); SEMANTIC(( $$ = $1 )); } | { RULES_DEBUG_printf("opt_instructions ->.\n"); SEMANTIC(( $$ = NULL )); } ; module_code_end: IDENTIFIER { RULES_DEBUG_printf("module_code_end -> IDENTIFIER .\n"); } | { RULES_DEBUG_printf("module_code_end -> .\n"); } ; opt_declarations: { RULES_DEBUG_printf("opt_declarations -> .\n"); } | declarations handlers_declaration { RULES_DEBUG_printf("opt_declarations -> declarations handlers_declaration.\n"); } | handlers_declaration { RULES_DEBUG_printf("opt_declarations -> handlers_declaration.\n"); } | declarations { RULES_DEBUG_printf("opt_declarations -> declarations .\n"); } ; declarations: declarations declaration endsentence { RULES_DEBUG_printf("declarations -> declarations declaration endsentence.\n"); } | declaration endsentence { RULES_DEBUG_printf("declarations -> declaration endsentence. \n"); } ; declaration: const_declaration { RULES_DEBUG_printf("declaration -> const_declaration.\n"); } | variables_declaration { RULES_DEBUG_printf("declaration -> variables_declaration.\n"); } | unit_module { RULES_DEBUG_printf("declaration -> unit_module.\n"); } | signal_declaration { RULES_DEBUG_printf("declarations -> signal_declaration.\n"); } ; opt_visibility_declarations: visibility_declarations { RULES_DEBUG_printf("opt_visibility_declarations -> visibility_declarations.\n"); } | { RULES_DEBUG_printf("opt_visibility_declarations -> .\n"); } ; visibility_declarations: visibility_declarations visibility_declaration endsentence { RULES_DEBUG_printf("visibility_declarations -> visibility_declarations visibility_declaration endsentence.\n"); } | visibility_declaration endsentence { RULES_DEBUG_printf("visibility_declarations ->visibility_declaration endsentence.\n"); } ; visibility_declaration: visibility_keyword identifier_list { RULES_DEBUG_printf("visibility_declaration -> visibility_keyword identifier_list.\n"); } ; visibility_keyword: TAKEN { RULES_DEBUG_printf("visibility_keyword -> TAKEN.\n"); } | CLOSE { RULES_DEBUG_printf("visibility_declarations -> CLOSE.\n"); } | HIDDEN { RULES_DEBUG_printf("visibility_declarations -> HIDDEN.\n"); } ; variables_declaration: VAR vars_list { RULES_DEBUG_printf("variables_declaration -> VAR vars_list.\n"); } ; const_declaration: CONST const_list { RULES_DEBUG_printf("variables_declaration -> CONST const_list.\n"); } ; signal_declaration: SIGNAL IDENTIFIER parameters { RULES_DEBUG_printf("signal_declaration -> SIGNAL IDENTIFIER parameters.\n");} ; // instructions are composed of juxtaposition of several instruction. instructions: instruction { RULES_DEBUG_printf("instructions -> instruction.\n"); SEMANTIC(( $$ = new Block( $1 ) )); } | instructions instruction { RULES_DEBUG_printf("instructions -> instructions instruction.\n"); SEMANTIC(( *$1 += $2 )); } ; // An Instruction could be a single instruction (like WRITE or STOP) // or a complex instruction (i.e. composed ) (like IF FOR WHILE CASE ... ) instruction: single_instruction endsentence { RULES_DEBUG_printf("instruction -> single_instruction endsentence.\n"); SEMANTIC(( $$ = $1 )); } | complex_instruction { RULES_DEBUG_printf("instruction -> complex_instruction.\n"); SEMANTIC(( $$ = $1 )); } ; // List of every single instruction available single_instruction: affectation_instruction { RULES_DEBUG_printf("instruction -> affectation_instruction.\n"); SEMANTIC(( $$ = $1 )); } | job_instruction { RULES_DEBUG_printf("instruction -> job_instruction.\n"); SEMANTIC(( $$ = $1 )); } | io_instruction { RULES_DEBUG_printf("instruction -> io_instruction.\n"); } | signal_instruction { RULES_DEBUG_printf("instruction -> signal_instruction.\n"); } | array_instruction { RULES_DEBUG_printf("instruction -> array_instruction.\n"); } | object_instruction { RULES_DEBUG_printf("instruction -> object_instruction.\n"); } | CALL variable { RULES_DEBUG_printf("instruction -> CALL variable.\n"); } | RETURN { RULES_DEBUG_printf("instruction -> RETURN.\n"); } | exit_instruction { RULES_DEBUG_printf("instruction -> exit_instruction.\n"); } ; // Subdivision of complex instructions : // instruction declaring a loop // instruction declaring a condition // instruction declaring a sub-block complex_instruction: loop_instruction { RULES_DEBUG_printf("complex_instruction -> loop_instruction.\n"); $$ = $1; } | condition_instruction { RULES_DEBUG_printf("complex_instruction -> condition_instruction.\n"); } | block_instruction { RULES_DEBUG_printf("complex_instruction -> block_instruction.\n"); } | case_instruction { RULES_DEBUG_printf("complex_instruction -> case_instruction.\n"); } ; vars_list: vars_list LIST_SEPARATOR var_declaration { RULES_DEBUG_printf("vars_list -> vars_list LIST_SEPARATOR var_declaration .\n"); } | var_declaration { RULES_DEBUG_printf("vars_list -> var_declaration .\n"); } ; const_list: const_list LIST_SEPARATOR one_const { RULES_DEBUG_printf("const_list -> const_list LISTSEPARATOR one_const.\n");} | one_const { RULES_DEBUG_printf("const_list -> one_const.\n");} ; one_const: IDENTIFIER EQUAL expression { RULES_DEBUG_printf("one_const -> IDENTIFIER EQUAL expression. \n"); } ; expression: one_or_more_logic_term { RULES_DEBUG_printf("expression -> one_or_more_logic_term.\n"); SEMANTIC(( $$ = $1 )); } ; one_or_more_logic_term: one_or_more_logic_factor { RULES_DEBUG_printf("one_or_more_logic_term -> one_or_more_logic_term.\n"); SEMANTIC(( $$ = $1 )) ; } | one_or_more_logic_term OR one_or_more_logic_factor { RULES_DEBUG_printf("one_or_more_logic_term -> one_or_more_logic_term OR one_or_more_logic_factor.\n"); SEMANTIC(( $$ = new BoolOperator( $1, $3 , Or, $2 ) )); } ; one_or_more_logic_factor: composed_expr { RULES_DEBUG_printf("one_or_more_logic_factor -> composed_expr.\n"); SEMANTIC(( $$ = $1 )); } | one_or_more_logic_factor AND composed_expr { RULES_DEBUG_printf("one_or_more_logic_factor -> one_or_more_logic_factor AND composed_expr.\n"); SEMANTIC(( $$ = new BoolOperator( $1, $3, And, $2 ) )); } ; composed_expr: NOT composed_expr2 { RULES_DEBUG_printf("composed_expr -> NOT composed_expr2.\n"); SEMANTIC(( $$ = new Not( $2,$1 ) )); } | composed_expr2 { RULES_DEBUG_printf("composed_expr -> composed_expr2.\n"); SEMANTIC(( $$ = $1 )); } ; composed_expr2: logic_expr { RULES_DEBUG_printf("composed_expr2 -> logic_expr.\n"); SEMANTIC(( $$ = $1 )); } | logic_expr binary_operator logic_expr { RULES_DEBUG_printf("composed_expr2 -> logic_expr binary_operator logic_expr.\n"); SEMANTIC(( $$ = new BoolOperator( $1 , $3 , $2 ) )); } | logic_expr object_operator object { RULES_DEBUG_printf("composed_expr2 -> logic_expr object_operator logic_expr.\n"); SEMANTIC(( $$ = new ObjOperator( $1 , $3 , $2 ) )); } ; binary_operator: EQUAL { RULES_DEBUG_printf("binary_operator -> EQUAL.\n"); SEMANTIC(($$ = Equal)); } | NEQUAL { RULES_DEBUG_printf("binary_operator -> NEQUAL.\n"); SEMANTIC(($$ = NotEqual)); } | LESS { RULES_DEBUG_printf("binary_operator -> LESS.\n"); SEMANTIC(($$ = Less)); } | LESSOREQUAL { RULES_DEBUG_printf("binary_operator -> LESSOREQUAL.\n"); SEMANTIC(($$ = LessOrEqual)); } | GREATER { RULES_DEBUG_printf("binary_operator -> GREATER.\n"); SEMANTIC(($$ = Greater)); } | GREATEROREQUAL { RULES_DEBUG_printf("binary_operator -> GREATEROREQUAL.\n"); SEMANTIC(($$ = GreaterOrEqual)); } ; object_operator: IS { RULES_DEBUG_printf("object_operator -> IS.\n"); SEMANTIC(( $$ = Is )); } | IN { RULES_DEBUG_printf("object_operator -> IN.\n"); SEMANTIC(( $$ = In )); } ; object: COROUTINE { RULES_DEBUG_printf("object -> COROUTINE.\n"); } | PROCESS { RULES_DEBUG_printf("object -> PROCESS.\n"); } | IDENTIFIER { RULES_DEBUG_printf("object -> IDENTIFIER.\n"); SEMANTIC(( $$ = new Identifier( $1.Str, $1.Loc ) )); } | error { RULES_ERROR_printf("error : bad object.\n"); SEMANTIC(( $$ = new Error( new Location( ThisPlace ) )); } ; logic_expr: opt_prefix_sign one_or_more_term { RULES_DEBUG_printf("expression -> opt_prefix_sign one_or_more_term.\n"); // To be modified, must take care of the optionnal prefix sign. SEMANTIC(( $$ = $2 )); } ; // The optionnal prefixing sign: +a, -a, a opt_prefix_sign: PLUS { RULES_DEBUG_printf("opt_prefix_sign -> PLUS.\n"); SEMANTIC(( $$.Int = 1 )); SEMANTIC(( $$.Loc = $1 )); } | MINUS { RULES_DEBUG_printf("opt_prefix_sign -> MINUS.\n"); SEMANTIC(( $$.Int = -1 )); SEMANTIC(( $$.Loc = $1)); } | { RULES_DEBUG_printf("opt_prefix_sign -> .\n"); SEMANTIC(( $$.Int = 1 )); SEMANTIC(( $$.Loc = new Location(ThisPlace) )); } ; one_or_more_term: one_or_more_factor { RULES_DEBUG_printf("one_or_more_term -> one_or_more_factor.\n"); SEMANTIC(($$ = $1)); } | one_or_more_term arith_operator one_or_more_factor { RULES_DEBUG_printf("one_or_more_term -> one_or_more_term arith_operator one_or_more_factor.\n"); SEMANTIC(( $$ = new ArithOperator( $1 , $3 , $2 ) )); } ; one_or_more_factor: factor { RULES_DEBUG_printf("one_or_more_factor -> factor.\n"); SEMANTIC(($$ = $1)); } | one_or_more_factor arith_operator2 factor { RULES_DEBUG_printf("one_or_more_factor -> one_or_more_factor arith_operator2 factor.\n"); SEMANTIC(( $$ = new ArithOperator( $1 , $3 , $2 ) )); } ; arith_operator: PLUS { RULES_DEBUG_printf("arith_operator -> PLUS.\n"); SEMANTIC(($$ = Plus)); } | MINUS { RULES_DEBUG_printf("arith_operator -> MINUS.\n"); SEMANTIC(($$ = Minus)); } ; arith_operator2: STAR { RULES_DEBUG_printf("arith_operator2 -> STAR.\n"); SEMANTIC(($$ = Multiply)); } | DIVIDE { RULES_DEBUG_printf("arith_operator2 -> DIVIDE.\n"); SEMANTIC(($$ = Divide)); } | DIV { RULES_DEBUG_printf("arith_operator2 -> DIV.\n"); SEMANTIC(($$ = IntDivide)); } | MOD { RULES_DEBUG_printf("arith_operator2 -> MOD.\n"); SEMANTIC(($$ = Modulo)); } ; factor: NumberConst { RULES_DEBUG_printf("factor -> NumberConst.\n"); SEMANTIC(( $$ = $1 )); } | TEXTCONST { RULES_DEBUG_printf("factor -> TextConst.\n"); SEMANTIC(( $$ = new StringConstant ( $1.Str, $1.Loc ) )); } | CHARCONST { RULES_DEBUG_printf("factor -> CharConst.\n"); SEMANTIC(( $$ = new CharConstant( $1.Str, $1.Loc ) )); } | BOOLCONST { RULES_DEBUG_printf("factor -> BOOLCONST.\n"); SEMANTIC(( $$ = new BoolConstant( $1.Bool, $1.Loc ) )); } | variable { RULES_DEBUG_printf("factor -> variable.\n"); SEMANTIC(( $$ = $1 )); } | object_factor { RULES_DEBUG_printf("factor -> object_factor.\n"); SEMANTIC(( $$ = $1 )); } | generator { RULES_DEBUG_printf("factor -> generator.\n"); SEMANTIC(( $$ = $1 )); } | expression_in_bracket { RULES_DEBUG_printf("factor -> expression_in_bracket.\n"); SEMANTIC(($$ = $1)); } | error { RULES_ERROR_printf(" error : bad factor.\n"); SEMANTIC(($$ = new Error )); } ; // Two results possible : an Integer constant if syntaxic string looks like // 1000 or 1E3. // or a Real constant if it looks like // 1.3 1E-3, etc... NumberConst: DIGITSEQUENCE opt_Num_const { RULES_DEBUG_printf("NumberConst -> DIGITSEQUENCE opt_Num_const.\n"); SEMANTIC( { if ($2 >= 1) { $$ = new IntegerConstant((int)($1.Int * $2.Real), new Location(*$1.Loc + *$2.Loc)); } else { $$ = new RealConstant( $1 * $2, new Location(*$1.Loc + *$2.Loc)); } }) } | DIGITSEQUENCE POINT DIGITSEQUENCE opt_Num_const { RULES_DEBUG_printf("NumberConst -> DIGITSEQUENCE POINT DIGITSEQUENCE opt_Num_const.\n"); SEMANTIC( { double dec = $3.Int; while (dec > 1) dec /= 10; dec += $1; $$ = new RealConstant( dec * $4 ); }) } | DIGITSEQUENCE POINT opt_Num_const { RULES_DEBUG_printf("NumberConst -> DIGITSEQUENCE POINT opt_Num_const.\n"); SEMANTIC( { printf("Valeur numerique : "); $$ = new RealConstant( $1 * $3 ); }) } | POINT DIGITSEQUENCE opt_Num_const { RULES_DEBUG_printf("NumberConst -> POINT DIGITSEQUENCE opt_Num_const.\n"); SEMANTIC( { double dec = $2; while (dec > 1) dec /= 10; $$ = new RealConstant( dec * $3 ); }) } ; // The IDENTIFIER must be the E letter for the analyse of an sci notated value // ( for example 1E-2 ). opt_Num_const: IDENTIFIER opt_prefix_sign DIGITSEQUENCE { RULES_DEBUG_printf("opt_Num_const -> IDENTIFIER opt_prefix_sign DIGITSEQUENCE.\n"); SEMANTIC( { if ( *$1 == "E" ) $$ = pow( 10 , (double) $3 * $2 ); else printf("Error : E was expected.\n"); }) } | { RULES_DEBUG_printf("opt_Num_const -> .\n"); SEMANTIC(( $$ = 1 )); } | IDENTIFIER error { RULES_DEBUG_printf(" error : exponant value expected.\n"); SEMANTIC(( $$ = 1 )); } ; object_factor: NONE { RULES_DEBUG_printf("object_factor -> NONE.\n"); SEMANTIC(( $$ = new NoneObject )); } | THIS IDENTIFIER { RULES_DEBUG_printf("object_factor -> THIS IDENTIFIER.\n"); SEMANTIC(( $$ = new This( new Identifier ($2 ) ) )); } | THIS error { RULES_ERROR_printf(" error : IDENTIFIER expected.\n"); } ; qualifier_expr: non_prefixed_variable { RULES_DEBUG_printf("qualifier_expr -> non_prefixed_variable.\n"); } | non_prefixed_generator { RULES_DEBUG_printf("qualifier_expr -> non_prefixed_generator.\n"); } ; opt_qualifier: qualifier_expr opt_qua_list POINT { RULES_DEBUG_printf("opt_qualifier -> qualifier_expr opt_qua_list POINT.\n"); } | THIS IDENTIFIER opt_qua_list POINT { RULES_DEBUG_printf("opt_qualifier -> THIS IDENTIFIER opt_qua_list POINT.\n"); } | THIS error { RULES_DEBUG_printf(" error : IDENTIFIER expected.\n"); } ; opt_qua_list: opt_qua_list QUA IDENTIFIER { RULES_DEBUG_printf("opt_qua_list -> QUA IDENTIFIER.\n"); } | { RULES_DEBUG_printf("opt_qua_list -> .\n"); } | opt_qua_list QUA error { RULES_ERROR_printf(" error : bad qua list (IDENTIFIER is missing).\n"); } ; opt_list_qualifier: opt_list_qualifier opt_qualifier { RULES_DEBUG_printf("opt_list_qualifier -> opt_list_qualifier opt_qualifier.\n"); } | opt_qualifier { RULES_DEBUG_printf("opt_list_qualifier -> opt_qualifier.\n"); } ; variable: opt_list_qualifier non_prefixed_variable { RULES_DEBUG_printf("variable -> opt_list_qualifier non_prefixed_variable.\n"); SEMANTIC(( $$ = $2 )); } | non_prefixed_variable { RULES_DEBUG_printf("variable -> non_prefixed_variable.\n"); SEMANTIC(( $$ = $1 )); } ; non_prefixed_variable: RESULT { RULES_DEBUG_printf("non_prefixed_variable -> RESULT.\n"); SEMANTIC(( $$ = new Result )); } | identifier_path { RULES_DEBUG_printf("non_prefixed_variable -> identifier_path.\n"); SEMANTIC(( $$ = new Identifier( $1 ) )); } | identifier_path OPENINGBRACKET one_or_more_expression CLOSINGBRACKET { RULES_DEBUG_printf("non_prefixed_variable -> identifier_path OPENINGBRACKET one_or_more_expression CLOSINGBRACKET.\n"); SEMANTIC(( $$ = new Identifier( $1 ) )); } ; one_or_more_expression: expression { RULES_DEBUG_printf("one_or_more_expression -> expression.\n"); } | one_or_more_expression LIST_SEPARATOR expression { RULES_DEBUG_printf("one_or_more_expression -> one_or_more_expression LIST_SEPARATOR expression.\n"); } ; generator: opt_list_qualifier non_prefixed_generator { RULES_DEBUG_printf("generator -> opt_list_qualifier non_prefixed_generator.\n"); SEMANTIC(( $$ = $2 )); } | non_prefixed_generator { RULES_DEBUG_printf("generator -> non_prefixed_generator.\n"); SEMANTIC(( $$ = $1 )); } ; non_prefixed_generator: NEW identifier_path actual_parameters { RULES_DEBUG_printf(" non_prefixed_generator -> NEW identifier_path actual_paramters.\n"); SEMANTIC(( $$ = new New( new Identifier( $2 ) ) )); } | NEW ARRAY OPENINGBRACKET expression LIST_SEPARATOR expression CLOSINGBRACKET { RULES_DEBUG_printf("non_prefixed_generator -> NEW ARRAY OPENINGBRACKET expression VARSEPARATOR expression CLOSINGBRACKET"); SEMANTIC(( $$ = new Error )); } | NEW error { RULES_DEBUG_printf(" error : IDENTIFIER or ARRAY expected.\n"); } | NEW ARRAY error { RULES_DEBUG_printf(" error : syntax error in array definition.\n"); } ; actual_parameters: | OPENINGBRACKET actual_parameters_list CLOSINGBRACKET { RULES_DEBUG_printf(" actual_parameters -> OPENINGBRACKET actual_parameters_list CLOSINGBRACKET.\n"); } ; actual_parameters_list: actual_parameter { RULES_DEBUG_printf("actual_paramters_list -> actual_parameter.\n"); } | actual_parameters_list LIST_SEPARATOR actual_parameter { RULES_DEBUG_printf("actual_parameters_list -> actual_parameters_list LIST_SEPARATOR actual_parameter.\n"); } ; actual_parameter: expression { RULES_DEBUG_printf("actual_parameter -> expression.\n"); } | predefinedtype { RULES_DEBUG_printf("actual_parameter -> predefinedtype.\n"); } ; affectation_instruction: l_identifiers_list AFFECTATION r_value { RULES_DEBUG_printf("affectation_instruction -> l_identifiers_list AFFECTATION r_value.\n"); SEMANTIC(( $$ = new Affectation( $1 , $3 ) )); } | l_identifiers_list error r_value { RULES_ERROR_printf("error : ':=' expected.\n"); SEMANTIC(( $$ = new Affectation( $1 , $3 ) )); } ; //** Warning !!! Theses actions are to be replaced by something right //** It's just Test Code . l_identifiers_list: variable { RULES_DEBUG_printf("l_identifiers_list -> variable.\n"); SEMANTIC(( $$ = $1 )); } | l_identifiers_list LIST_SEPARATOR variable { RULES_DEBUG_printf("l_identifiers_list -> l_identifiers_list LIST_SEPARATOR variable.\n"); SEMANTIC(( $$ = $3 )); } ; r_value: expression { RULES_DEBUG_printf("r_value -> expression .\n"); SEMANTIC(( $$ = $1 )); } | COPY expression_in_bracket { RULES_DEBUG_printf("r_value -> COPY expression_in_bracket .\n"); SEMANTIC(( $$ = new Copy( $2 ) )); } ; job_instruction: parameter_job_instruction OPENINGBRACKET expression CLOSINGBRACKET { RULES_DEBUG_printf("job_instruction -> parameter_job_instruction ( expression ).\n"); SEMANTIC( { switch($1) { case AttachInstr: $$ = new Attach( $3 ); break; case ResumeInstr: $$ = new Resume( $3 ); break; case StopInstr: $$ = new Stop( $3 ); break; } }); } | DETACH { RULES_DEBUG_printf("job_instruction -> DETACH.\n"); SEMANTIC(( $$ = new Detach )); } | STOP { RULES_DEBUG_printf("job_instruction -> STOP.\n"); SEMANTIC(( $$ = new Stop )); } | TERMINATE { RULES_DEBUG_printf("job_instruction -> TERMINATE.\n"); SEMANTIC(( $$ = new Terminate )); } ; parameter_job_instruction: ATTACH { RULES_DEBUG_printf("parameter_job_instruction -> ATTACH.\n"); SEMANTIC(( $$ = AttachInstr )); } | RESUME { RULES_DEBUG_printf("parameter_job_instruction -> RESUME.\n"); SEMANTIC(( $$ = ResumeInstr )); } | STOP { RULES_DEBUG_printf("parameter_job_instruction -> STOP.\n"); SEMANTIC(( $$ = StopInstr )); } ; io_instruction: file_io_instruction { RULES_DEBUG_printf("io_instruction -> file_io_instruction .\n"); } | input_instruction { RULES_DEBUG_printf("io_instruction -> input_instruction .\n"); } | output_instruction { RULES_DEBUG_printf("io_instruction -> output_instruction .\n"); } ; file_io_instruction: file_io_keyword OPENINGBRACKET expression LIST_SEPARATOR one_or_more_expression CLOSINGBRACKET { RULES_DEBUG_printf("file_io_instruction -> file_io_keyword ( expression LIST_SEPARATOR one_or_more_expression ).\n"); } ; file_io_keyword: PUT { RULES_DEBUG_printf("file_io_keyword -> PUT.\n"); } | GET { RULES_DEBUG_printf("file_io_keyword -> GET.\n"); } ; input_instruction: input_keyword OPENINGBRACKET l_identifiers_list CLOSINGBRACKET { RULES_DEBUG_printf("input_instruction -> input_keyword ( l_identifiers_list ).\n"); } | READLN { RULES_DEBUG_printf("input_instruction -> READLN.\n"); } ; input_keyword: READ { RULES_DEBUG_printf("input_keyword -> READ.\n"); } | READLN { RULES_DEBUG_printf("input_keyword -> READLN.\n"); } ; output_instruction: output_keyword OPENINGBRACKET l_formated_identifiers_list CLOSINGBRACKET { RULES_DEBUG_printf("output_instructions -> output_keyword ( l_formated_identifiers_list ).\n"); } | WRITELN { RULES_DEBUG_printf("output_instructions -> WRITELN.\n"); } ; output_keyword: WRITE { RULES_DEBUG_printf("output_keyword -> WRITE.\n"); } | WRITELN { RULES_DEBUG_printf("output_keyword -> WRITELN.\n"); } ; l_formated_identifiers_list: expression opt_modifiers { RULES_DEBUG_printf("l_formatted_identifiers_list -> expression opt_modifiers.\n"); } | l_formated_identifiers_list LIST_SEPARATOR expression opt_modifiers { RULES_DEBUG_printf("l_formatted_identifiers_list -> l_formated_identifiers_list LIST_SEPARATOR expression opt_modifiers.\n"); } ; opt_modifiers: VARSEPARATOR NumberConst opt_modifiers2 { RULES_DEBUG_printf(" opt_modifiers -> VARSEPARATOR NumberConst opt_modifiers2.\n");} | { RULES_DEBUG_printf(" opt_modifiers -> .\n");} ; opt_modifiers2: VARSEPARATOR NumberConst { RULES_DEBUG_printf(" opt_modifiers2 -> VARSEPARATOR NumberConst.\n");} | { RULES_DEBUG_printf(" opt_modifiers2 -> .\n");} ; signal_instruction: RAISE IDENTIFIER actual_parameters { RULES_DEBUG_printf("signal_instruction -> RAISE IDENTIFIER actual_parameters.\n"); } ; array_instruction: ARRAY variable DIM OPENINGBRACKET expression VARSEPARATOR expression CLOSINGBRACKET { RULES_DEBUG_printf("array_instruction -> ARRAY variable DIM OPENINGBRACKET expression VARSEPARATOR expression CLOSINGBRACKET.\n"); } ; exit_instruction: exit_list opt_repeat { RULES_DEBUG_printf("exit_instruction -> opt_exit_list opt_repeat.\n");} | REPEAT { RULES_DEBUG_printf("exit_instruction -> REPEAT.\n");} ; exit_list: exit_list EXIT { RULES_DEBUG_printf("opt_exit_list -> opt_exit_list EXIT.\n");} | EXIT { RULES_DEBUG_printf("opt_exit_list -> EXIT .\n");} ; opt_repeat: REPEAT { RULES_DEBUG_printf("opt_repeat -> REPEAT.\n");} | { RULES_DEBUG_printf("opt_repeat -> .\n");} ; loop_instruction: WHILE expression loop_body { RULES_DEBUG_printf("loop_header -> WHILE expression loop_body.\n"); SEMANTIC(( $$ = new While( $2, $3 ) )); } | FOR variable AFFECTATION expression DOWNTO expression loop_body { RULES_DEBUG_printf("loop_header -> FOR variable AFFECTATION expression DOWNTO expression loop_body.\n"); SEMANTIC(( $$ = new For( $2, $4, $6, new IntegerConstant( -1 ), $7 ) )); } | FOR variable AFFECTATION expression TO expression loop_body { RULES_DEBUG_printf("loop_header -> FOR variable AFFECTATION expression TO expression loop_body.\n"); SEMANTIC(( $$ = new For( $2, $4, $6, new IntegerConstant( 1 ), $7 ) )); } | FOR variable AFFECTATION expression TO expression STEP expression loop_body { RULES_DEBUG_printf("loop_header -> FOR variable AFFECTATION expression TO expression STEP expression loop_body.\n"); SEMANTIC(( $$ = new For( $2, $4, $6, $8, $9 ) )); } ; loop_body: DO opt_instructions OD { RULES_DEBUG_printf("loop_body -> DO opt_instructions OD.\n"); SEMANTIC(( $$ = $2 )); } | DO opt_instructions error { RULES_ERROR_printf("error OD expected.\n"); SEMANTIC(( $$ = NULL )); } ; condition_instruction: IF short_or_and_list THEN opt_instructions opt_else FI { RULES_DEBUG_printf("condition_instruction -> IF short_or_and_list THEN opt_instructions opt_else FI.\n"); SEMANTIC(( $$ = new ConditionIf( $2, $4, $5 ) )); } | IF short_or_and_list error { RULES_ERROR_printf("error : THEN expected.\n"); } | IF short_or_and_list THEN opt_instructions opt_else error { RULES_ERROR_printf("error : FI or ELSE expected.\n"); } ; short_or_and_list: expression { RULES_DEBUG_printf("short_or_and_list -> expression.\n"); SEMANTIC(( $$ = $1 )); } // The two next rules are wrong because ORIF and ANDIF are supposed to have // the same priority. This has to be fixed. | short_or_and_list ORIF expression { RULES_DEBUG_printf("short_or_and_list -> short_or_and_list ORIF expression.\n"); SEMANTIC(( $$ = new BoolOperator( $1, $3, Or ) )); } | short_or_and_list ANDIF expression { RULES_DEBUG_printf("short_or_and_list -> short_or_and_list ANDIF expression.\n"); SEMANTIC(( $$ = new BoolOperator( $1, $3, And ) )); } ; opt_else: ELSE opt_instructions { RULES_DEBUG_printf("opt_else -> ELSE opt_instructions. \n"); SEMANTIC(( $$ = $2 )); } | { RULES_DEBUG_printf("opt_else -> . \n"); SEMANTIC(( $$ = NULL )); } ; case_instruction: CASE expression case_when_list opt_case_otherwise ESAC { RULES_DEBUG_printf("case_instruction -> CASE expression case_when_list opt_case_otherwise ESAC.\n"); } ; opt_case_otherwise: OTHERWISE opt_instructions { RULES_DEBUG_printf("opt_case_otherwise -> OTHERWISE opt_instructions.\n"); } | { RULES_DEBUG_printf("opt_case_otherwise -> .\n"); } ; case_when_list: one_when_case { RULES_DEBUG_printf("case_when_list -> one_when_case.\n"); } | case_when_list one_when_case { RULES_DEBUG_printf("case_when_list -> case_when_list one_when_case.\n"); } ; one_when_case: WHEN expression VARSEPARATOR opt_instructions { RULES_DEBUG_printf("one_when_case -> WHEN expression VARSEPARATOR opt_instructions.\n"); } ; object_instruction: WIND { RULES_DEBUG_printf("object_instruction -> WIND.\n"); } | INNER { RULES_DEBUG_printf("object_instruction -> INNER.\n"); } | KILL expression_in_bracket { RULES_DEBUG_printf("object_instruction -> KILL expression_in_bracket.\n"); } | generator { RULES_DEBUG_printf("object_instruction -> generator.\n"); } ; block_instruction: PREF IDENTIFIER actual_parameters BLOCK opt_block_taken module_body endsentence { RULES_DEBUG_printf("block_instruction -> PREF IDENTIFIER actual_parameters BLOCK opt_block_taken module_body endsentence.\n"); } ; opt_block_taken: TAKEN identifier_list endsentence { RULES_DEBUG_printf("opt_block_taken -> TAKEN identifier_list endsentence.\n"); } | { RULES_DEBUG_printf("opt_block_taken -> .\n"); } ; expression_in_bracket: OPENINGBRACKET expression CLOSINGBRACKET { RULES_DEBUG_printf("expression_in_bracket -> OPENINGBRACKET expression CLOSINGBRACKET.\n"); SEMANTIC(( $$ = $2 )); } | OPENINGBRACKET expression error { RULES_ERROR_printf("error : unbalanced bracket. \n"); } ; endprogram: ENDSENTENCE { RULES_DEBUG_printf("endprogram -> ENDSENTENCE.\n"); } | POINT { RULES_DEBUG_printf("endprogram -> POINT.\n"); } | error { RULES_ERROR_printf("error : ';' or '.' expected.\n"); } ; %% void initialize( void ) { BeginningOfLine = 1; } main() { yyparse(); } int yyerror( void ) { printf("Syntax error at line %d.\n",line_number); return 0; } int yyerror( char *s ) { printf("%s",s); return 0; }