#!/usr/bin/perl ################### ### Clause 9.1 ### ################### sub ALF_function { local($token,$parent) = @_; local ($object,$type); $type = $ALF_ParserData[$token]; &StringMatch($type,'FUNCTION') && ( ($object = &ALF_CreateObject($parent,$type)) && &ALF_SyntaxItems('function_item',$token+1,$object) || &ALF_SyntaxError('function',$token+1) ); } sub ALF_function_item { local($token,$object) = @_; &ALF_behavior($token,$object) || &ALF_structure($token,$object) || &ALF_statetable($token,$object) || &ALF_all_purpose_item($token,$object); } ################### ### Clause 9.2 ### ################### sub ALF_test { local($token,$parent) = @_; local ($object,$type); $type = $ALF_ParserData[$token]; &StringMatch($type,'TEST') && ( ($object = &ALF_CreateObject($parent,$type)) && &ALF_SyntaxItems('test_item',$token+1,$object) || &ALF_SyntaxError('test',$token+1) ); } sub ALF_test_item { local($token,$object) = @_; &ALF_behavior($token,$object) || &ALF_statetable($token,$object) || &ALF_all_purpose_item($token,$object); } ################### ### Clause 9.3 ### ################### $ALF_pin_variable = $ALF_identifier; $ALF_pin_value = join('$|^', $ALF_boolean_value, $ALF_pin_variable, ); sub ALF_pin_assignment { local($token,$parent) = @_; &ALF_LexicalRule('pin_variable',$token) && $ALF_ParserData[$token+1] eq '=' && &ALF_LexicalRule('pin_value',$token+2) && $ALF_ParserData[$token+3] eq ';' && &ALF_CreateObject($parent,$ALF_ParserData[$token],0,$ALF_ParserData[$token+2]) && $token+3; } ################### ### Clause 9.4 ### ################### sub ALF_behavior { local($token,$parent) = @_; local ($object,$type); $type = $ALF_ParserData[$token]; &StringMatch($type,'BEHAVIOR') && ( ($object = &ALF_CreateObject($parent,$type)) && &ALF_SyntaxItems('behavior_item',$token+1,$object) || &ALF_SyntaxError('behavior',$token+1) ); } sub ALF_behavior_item { local($token,$object) = @_; &ALF_boolean_assignment($token,$object) || &ALF_control_statement($token,$object) || &ALF_primitive_instantiation($token,$object); } sub ALF_boolean_assignment { local($token,$parent) = @_; local ($type,$value,$start,$end); $type = $ALF_ParserData[$token]; &ALF_LexicalRule('pin_variable',$token) && $ALF_ParserData[$token+1] eq '=' && ($start = $token+2) && ($end = &ALF_boolean_expression($start)) && (($value = join(' ',&GetSubArray('ALF_ParserData',$start,$end))) || defined($value)) && &ALF_CreateObject($parent,$type,0,$value) && ( $ALF_ParserData[$end+1] eq ';' && $end+1 || &ALF_SyntaxError('boolean_assignment',$end+1) ); } sub ALF_control_statement { local($token,$object) = @_; local $next = &ALF_primary_control_statement($token,$object); while ($next) { $token = $next; $next = &ALF_alternative_control_statement($token+1,$object); } $token; } sub ALF_primary_control_statement { local($token,$parent) = @_; local ($object,$type,$name,$start,$end,$list,%array); $type = $ALF_ParserData[$token]; &StringMatch($type,'@') && ( ($start = $token + 1) && ($list = &AutoName) && ($end = &ALF_control_expression($start,$list) || &ALF_SyntaxError('control_expression',$start)) && ($name = join(' ',&GetSubArray('ALF_ParserData',$start,$end))) && (%array = %ALF_ExpressionToken) && ($object = &ALF_CreateObject($parent,$type,$name)) && ($ALF_Expression{$object} = &CreateArray(sort(ByAscendingAssocVal &Array($list)))) && &ALF_SyntaxItems('boolean_assignment',$end+1,$object) || &ALF_SyntaxError('primary_control_statement',$token) ); } sub ALF_alternative_control_statement { local($token,$parent) = @_; local ($object,$type,$name,$start,$end,$list,%array); $type = $ALF_ParserData[$token]; &StringMatch($type,':') && ( ($start = $token + 1) && ($list = &AutoName) && ($end = &ALF_control_expression($start,$list) || &ALF_SyntaxError('control_expression',$start)) && ($name = join(' ',&GetSubArray('ALF_ParserData',$start,$end))) && (%array = %ALF_ExpressionToken) && ($object = &ALF_CreateObject($parent,$type,$name)) && ($ALF_Expression{$object} = &CreateArray(sort(ByAscendingAssocVal &Array($list)))) && &ALF_SyntaxItems('boolean_assignment',$end+1,$object) || &ALF_SyntaxError('alternative_control_statement',$token) ); } ### reference by order not yet implemented sub ALF_primitive_instantiation { local($token,$parent) = @_; local ($object,$type,$name); $type = $ALF_ParserData[$token]; $name = $ALF_ParserData[$token+1] if &ALF_LexicalRule('identifier',$token+1); $token = $name? $token + 2 : $token + 1; &ALF_SyntaxMatch('primitive_instantiation',&UpperCase($type),$parent) && ( ($object = &ALF_CreateObject($parent,$type)) && &ALF_DefineReferenceRule($object,'boolean_assignment') && &ALF_SyntaxItems('boolean_assignment',$token,$object) || &ALF_SyntaxError('primitive_instantiation',$token) ); } ################### ### Clause 9.5 ### ################### sub ALF_structure { local($token,$parent) = @_; local ($object,$type); $type = $ALF_ParserData[$token]; &StringMatch($type,'STRUCTURE') && ( ($object = &ALF_CreateObject($parent,$type)) && &ALF_SyntaxItems('cell_instantiation',$token+1,$object) || &ALF_SyntaxError('structure',$token+1) ); } ### reference by order not yet implemented sub ALF_cell_instantiation { local($token,$parent) = @_; local ($object,$type,$name); $type = $ALF_ParserData[$token]; $name = $ALF_ParserData[$token+1]; &ALF_SyntaxMatch('cell_instantiation',&UpperCase($type),$parent) && ( ($object = &ALF_CreateObject($parent,$type)) && &ALF_DefineReferenceRule($object,'pin_assignment') && &ALF_SyntaxItems('pin_assignment',$token+2,$object) || &ALF_SyntaxError('cell_instantiation',$token) ); } ################### ### Clause 9.6 ### ################### sub ALF_statetable { local($token,$parent) = @_; local ($object,$type,$name,$value,$start,$end); $type = $ALF_ParserData[$token]; $name = $ALF_ParserData[$token+1] if &ALF_LexicalRule('identifier',$token+1); $start = $name? $token + 3 : $token + 2; &StringMatch($type,'STATETABLE') && ( ($object = &ALF_CreateObject($parent,$type,$name)) && ($ALF_ParserData[$start-1] eq '{') && ($token = &ALF_statetable_header($start)) && ($end = &ALF_SyntaxItems('statetable_row',$token+1,$object)) && ($ALF_ParserData[$end+1] eq '}') && ($value = &CreateSubArray('ALF_ParserData',$start,$end)) && ($ALF_Value{$object} = $value) && ($ALF_ArrayFormat{$value} = $token-$start) && $end+1 || &ALF_SyntaxError('statetable',$start-1) ); } sub ALF_statetable_header { local($token) = @_; local ($input_until,$output_until); $input_until = 1 + &ALF_LexicalItems('pin_variable',$token); ($input_until > $token+1) || &ALF_SyntaxError('statetable_header',$token+1); ($ALF_ParserData[$input_until] eq ':') || &ALF_SyntaxError('statetable_header',$input_until); $output_until = 1 + &ALF_LexicalItems('pin_variable',$input_until+1); ($output_until > $input_until+2) || &ALF_SyntaxError('statetable_header',$input_until+2); ($ALF_ParserData[$output_until] eq ';') || &ALF_SyntaxError('statetable_header',$output_until); $output_until; } sub ALF_statetable_row { local($token) = @_; local ($control_until,$data_until); $control_until = 1 + &ALF_LexicalItems('statetable_control_value',$token+1); ($control_until > $token+1) || &ALF_SyntaxError('statetable_row',$token+1); ($ALF_ParserData[$control_until] eq ':') || &ALF_SyntaxError('statetable_row',$control_until); $data_until = 1 + &ALF_LexicalItems('statetable_data_value',$control_until+1); ($output_until > $control_until+1) || &ALF_SyntaxError('statetable_row',$control_until+1); ($ALF_ParserData[$data_until] eq ';') || &ALF_SyntaxError('statetable_row',$data_until); $data_until; } $ALF_statetable_control_value = join('$|^', $ALF_boolean_value, $ALF_symbolic_bit_literal, $ALF_edge_value, ); $ALF_statetable_data_value = join('$|^', $ALF_boolean_value, join('\)$|^\([!|~]?',split(/\$\|\^/,$ALF_pin_variable)), ); ################### ### Clause 9.7 ### ################### ### reference by order not yet implemented sub ALF_non_scan_cell { local($token,$parent) = @_; local ($object,$type,$value); $type = $ALF_ParserData[$token]; &StringMatch($type,'NON_SCAN_CELL') && ( ($object = &ALF_CreateObject($parent,$type)) && ( $ALF_ParserData[$token+1] eq '=' && ($ALF_Value{$object} = $ALF_ParserData[$token+2]) && &ALF_non_scan_cell_reference($token+2,$parent,$object) || &ALF_SyntaxItems('non_scan_cell_reference',$token+1,$parent) ) || &ALF_SyntaxError('non_scan_cell',$token) ); } ### Note: pin_assignment is an implicit interpretation ### within the syntax rule for non_scan_cell_reference ### See also clause 9.3 sub ALF_non_scan_cell_reference { local($token,$parent,$object) = @_; &ALF_LexicalRule('identifier',$token) || &ALF_SyntaxError('non_scan_cell_reference',$token); unless (defined($object)) { $type = $ALF_ParserData[$token]; $object = &ALF_CreateObject($parent,$type); } &ALF_SyntaxItems('pin_assignment',$token+1,$object) || &ALF_SyntaxError('non_scan_cell_reference',$token+1); } ################### ### Clause 9.8 ### ################### sub ALF_range { local($token,$parent) = @_; local ($object,$type,$value); $type = $ALF_ParserData[$token]; &StringMatch($type,'RANGE') && ( ($object = &ALF_CreateObject($parent,$type)) && $ALF_ParserData[$token+1] eq '{' && &ALF_LexicalRule('index_value',$token+2) && $ALF_ParserData[$token+3] eq ':' && &ALF_LexicalRule('index_value',$token+4) && $ALF_ParserData[$token+5] eq '}' || &ALF_SyntaxError('non_scan_cell',$token) ); } ################### ### Clause 9.9 ### ################### ### Note: boolean_expression rule cannot be directly implemented as formulated in the standard. ### The naive implementation of the rule will lead to a false stop when boolean_value or identifier is detected: ### ... ### | '(' boolean_expression ')' ### | boolean value | identifier ### | boolean_expression boolean_binary_operator boolean_expression ### | boolean_expression ? boolean_expression : boolean_expression ### ... ### Therefore we implement instead: ### ... ### | ( '(' boolean_expression ')' | boolean value | identifier ) ### [ boolean_binary_operator boolean_expression ### | ? boolean_expression : boolean_expression ] ### ... sub ALF_boolean_expression { local($token,*list) = @_; $ALF_Debug > 1 && print("# ALF Syntax Info:\tboolean expression evaluation started at $token\n"); local $nexttoken; ( $ALF_ParserData[$token] eq '(' && ($nexttoken = &ALF_boolean_expression($token+1,*list)) && $ALF_ParserData[$nexttoken+1] eq ')' && &ALF_AssertExpressionRule('( boolean_expression )',$token,*list) && ($token = $nexttoken+1) || &ALF_LexicalRule('boolean_value',$token) && !&ALF_LexicalRule('edge_literal',$token) # avoid ambiguity && &ALF_AssertExpressionRule('boolean_value',$token,*list) || &ALF_LexicalRule('identifier',$token) && &ALF_AssertExpressionRule('identifier',$token,*list) ) && ( &ALF_LexicalRule('boolean_binary_operator',$token+1) && ! &ALF_vector_expression($token+2) # avoid ambiguity && ($nexttoken = &ALF_boolean_expression($token+2)) && &ALF_AssertExpressionRule('boolean_binary_operator boolean_expression',$token+1,*list) && ($token = $nexttoken) || $ALF_ParserData[$token+1] eq '?' && ($nexttoken = &ALF_boolean_expression($token+2)) && $ALF_ParserData[$nexttoken+1] eq ':' && ($nexttoken = &ALF_boolean_expression($nexttoken+2)) && &ALF_AssertExpressionRule('? boolean_expression : boolean_expression',$token+1,*list) && ($token = $nexttoken) || ($ALF_Debug < 2 || print("# ALF Syntax Info:\tboolean expression evaluation finished at $token\n")) && $token ) || &ALF_LexicalRule('boolean_unary_operator',$token) && ($nexttoken = &ALF_boolean_expression($token+1)) && &ALF_AssertExpressionRule('boolean_unary_operator boolean_expression',$token,*list) && ($token = $nexttoken) || ($ALF_Debug < 2 || print("# ALF Syntax Info:\tboolean expression evaluation failed at $token\n")) && 0 ; } $ALF_boolean_unary_operator = join('$|^', '[!~&\|\^]', '~&', '~\|', '~\^', ); $ALF_boolean_binary_operator = join('$|^', '[&\|\^]', '&&', '\|\|', '~&', '~\|', '~\^', split(/\|/,$ALF_relational_operator), split(/\|/,$ALF_arithmetic_operator), split(/\|/,$ALF_shift_operator), ); ################### ### Clause 9.10 ## ################### ### Boolean value system, semantics only ################### ### Clause 9.11 ## ################### ### Boolean operations and operators, semantics only ################### ### Clause 9.12 ## ################### ### Note: vector_expression rule cannot be directly implemented as formulated in the standard. ### The naive implementation of the rule will lead to a false stop when vector_expression_macro or single_event is detected: ### ... ### | '(' vector_expression ')' ### | vector_expression_macro ### | single_event ### | vector_expression vector_operator vector_expression ### | vector_expression control_and boolean_expression ### ... ### Therefore we implement instead: ### ... ### | ( '(' vector_expression ')' | vector_expression_macro | single_event ) ### [ vector_operator vector_expression ### | control_and boolean_expression ] ### ... sub ALF_vector_expression { local($token,*list) = @_; $ALF_Debug > 1 && print("# ALF Syntax Info:\tvector expression evaluation started at $token\n"); local $nexttoken; ( $ALF_ParserData[$token] eq '(' && ($nexttoken = &ALF_vector_expression($token+1)) && $ALF_ParserData[$nexttoken+1] eq ')' && &ALF_AssertExpressionRule('( vector_expression )',$token,*list) && ($ALF_Debug < 2 || print("# ALF Syntax Info:\tvector expression ends with \47)\47 at ",$token+1,"\n")) && ($token = $nexttoken+1) || &ALF_LexicalRule('vector_expression_macro',$token) && &ALF_AssertExpressionRule('vector_expression_macro',$token,*list) || ($nexttoken = &ALF_single_event($token)) && &ALF_AssertExpressionRule('single_event',$token,*list) && ($token = $nexttoken) && ( &ALF_LexicalRule('control_and',$token+1) && ($nexttoken = &ALF_boolean_expression($token+2)) && &ALF_AssertExpressionRule('control_and boolean_expression',$token+1,*list) && ($token = $nexttoken) || $token) ) && ( &ALF_LexicalRule('vector_operator',$token+1) && ($nexttoken = &ALF_vector_expression($token+2)) && &ALF_AssertExpressionRule('vector_operator vector_expression',$token+1,*list) && ($token = $nexttoken) || &ALF_LexicalRule('control_and',$token+1) && ($nexttoken = &ALF_boolean_expression($token+2)) && &ALF_AssertExpressionRule('control_and boolean_expression',$token+1,*list) && ($token = $nexttoken) || ($ALF_Debug < 2 || print("# ALF Syntax Info:\tvector expression evaluation finished at $token\n")) && $token ) || ($nexttoken = &ALF_boolean_expression($token)) && &ALF_AssertExpressionRule('boolean_expression',$token,*list) && ($token = $nexttoken) && ( &ALF_LexicalRule('control_and',$token+1) && ($nexttoken = &ALF_vector_expression($token+2)) && &ALF_AssertExpressionRule('control_and vector_expression',$token+1,*list) && ($token = $nexttoken) || $ALF_ParserData[$token+1] eq '?' && ($nexttoken = &ALF_vector_expression($token+2)) && $ALF_ParserData[$nexttoken+1] eq ':' && ($nexttoken = &ALF_vector_expression($nexttoken+2)) && &ALF_AssertExpressionRule('? vector_expression : vector_expression',$token+1,*list) && ($token = $nexttoken) || ($ALF_Debug < 2 || print("# ALF Syntax Info:\tboolean expression is not part of a vector expression at $token\n")) && 0 ) || ($ALF_Debug < 2 || print("# ALF Syntax Info:\tvector expression evaluation failed at $token\n")) && 0 ; } sub ALF_single_event { local($token) = @_; $ALF_Debug > 1 && print("# ALF Syntax Info:\tsingle event evaluation started at $token\n"); local ($savedata,$next); &ALF_LexicalRule('edge_literal',$token) && &ALF_single_event_expression($token+1) || (($savedata = $ALF_ParserData[$token]) || 1) && ($ALF_ParserData[$token] = $savedata.$ALF_ParserData[$token+1]) && &ALF_LexicalRule('edge_literal',$token) && ($next = &ALF_single_event_expression($token+2)) && (($ALF_ParserData[$token+1] = '') || 1) && $next || ($ALF_ParserData[$token] = $savedata) && 0 ; } sub ALF_single_event_expression { local($token,*list) = @_; $ALF_Debug > 1 && print("# ALF Syntax Info:\tsingle event expression evaluation started at $token\n"); local $nexttoken; ( $ALF_ParserData[$token] eq '(' && ($nexttoken = &ALF_boolean_expression($token+1,*list)) && $ALF_ParserData[$nexttoken+1] eq ')' && &ALF_AssertExpressionRule('( boolean_expression )',$token,*list) && ($token = $nexttoken+1) || &ALF_LexicalRule('identifier',$token) && &ALF_AssertExpressionRule('identifier',$token,*list) ) && ( ($ALF_Debug < 2 || print("# ALF Syntax Info:\tsingle event expression evaluation finished at $token\n")) && $token ) || ($ALF_Debug < 2 || print("# ALF Syntax Info:\tsingle event expression evaluation failed at $token\n")) && 0 ; } $ALF_event_and = '&&?'; $ALF_event_or = '\|\|?'; $ALF_vector_operator = join('$|^', split(/\|/,$ALF_event_operator), $ALF_event_and, $ALF_event_or, ); $ALF_control_and = '&&?'; sub ALF_control_expression { local($token,*list) = @_; local $nexttoken; $ALF_ParserData[$token] eq '(' && ( ($nexttoken = &ALF_vector_expression($token+1,*list)) || ($nexttoken = &ALF_boolean_expression($token+1,*list)) ) && $ALF_ParserData[$nexttoken+1] eq ')' && $nexttoken+1; } ################### ### Clause 9.13 ## ################### ### Specification of a pattern of events, semantics only ################### ### Clause 9.14 ## ################### ### Predefined PRIMITIVE, semantics only ################### ### Clause 9.15 ## ################### ### reference by order not yet implemented sub ALF_wire_instantiation { local($token,$parent) = @_; local ($object,$type,$name); $type = $ALF_ParserData[$token]; $name = $ALF_ParserData[$token+1]; &ALF_SyntaxMatch('wire_instantiation',&UpperCase($type),$parent) && ( ($object = &ALF_CreateObject($parent,$type)) && &ALF_DefineReferenceRule($object,'pin_assignment') && &ALF_SyntaxItems('pin_assignment',$token+2,$object) || &ALF_SyntaxError('wire_instantiation',$token) ); } ################### ### Clause 9.16 ## ################### sub ALF_geometric_model { local($token,$parent) = @_; local ($object,$type,$name); $type = $ALF_ParserData[$token]; $name = $ALF_ParserData[$token+1] if &ALF_LexicalRule('identifier',$token+1); &ALF_SyntaxMatch('geometric_model',$type,$parent) && ( ($object = &ALF_CreateObject($parent,$type,$name)) && ($token = $name? $token+2 : $token+1) && &ALF_SyntaxItems('geometric_model_item',$token,$object) || &ALF_SyntaxError('geometric_model',$token) ); } sub ALF_geometric_model_item { local($token,$parent) = @_; &ALF_single_value_annotation($token,$parent) || &ALF_coordinates($token,$parent); } sub ALF_coordinates { local($token,$parent) = @_; local ($object,$type,$start,$end); $type = $ALF_ParserData[$token]; &StringMatch($type,'COORDINATES') && ( $ALF_ParserData[$token+1] eq '{' && ($start = $token + 2) ### Errata: number should be arithmetic_value ### && ($end = &ALF_LexicalItems('number',$start)) && ($end = &ALF_LexicalItems('arithmetic_value',$start)) && ($object = &ALF_CreateObject($parent,$type,0,&CreateSubArray('ALF_ParserData',$start,$end))) && ($end - $start < 4 || (&ALF_ArrayFormat($ALF_Value{$object}) = 4)) && $ALF_ParserData[$end+1] eq '}' && $end+1 || &ALF_SyntaxError('coordinates',$token+1) ); } $ALF_SyntaxRule{'DOT'} = 'geometric_model'; $ALF_SyntaxRule{'POLYLINE'} = 'geometric_model'; $ALF_SyntaxRule{'RING'} = 'geometric_model'; $ALF_SyntaxRule{'POLYGON'} = 'geometric_model'; $ALF_SyntaxRule{'POLYLINE.POINT_TO_POINT'} = 'single_value_annotation'; $ALF_SyntaxRule{'RING.POINT_TO_POINT'} = 'single_value_annotation'; $ALF_SyntaxRule{'POLYGON.POINT_TO_POINT'} = 'single_value_annotation'; ################### ### Clause 9.17 ## ################### ### Predefined geometric models, semantics only ################### ### Clause 9.18 ## ################### sub ALF_geometric_transformation { local($token,$parent) = @_; &ALF_shift($token,$parent) || &ALF_rotate($token,$parent) || &ALF_flip($token,$parent) || &ALF_repeat($token,$parent); } sub ALF_shift { local($token,$parent) = @_; local ($object,$type); $type = $ALF_ParserData[$token]; &StringMatch($type,'SHIFT') && ( $ALF_ParserData[$token+1] eq '{' ### Errata: number should be arithmetic_value ### && $ALF_LexicalRule('number',$token+2,1) ### && $ALF_LexicalRule('number',$token+3,1) && &ALF_LexicalRule('arithmetic_value',$token+2,1) && &ALF_LexicalRule('arithmetic_value',$token+3,1) && $ALF_ParserData[$token+4] eq '}' && ($object = &ALF_CreateObject($parent,$type,0,&CreateSubArray('ALF_ParserData',$token+2,$token+3))) && $token+4 || &ALF_SyntaxError('shift',$token) ); } sub ALF_rotate { local($token,$parent) = @_; local ($object,$type); $type = $ALF_ParserData[$token]; &StringMatch($type,'ROTATE') && ( $ALF_ParserData[$token+1] eq '=' ### Errata: number should be arithmetic_value ### && &ALF_LexicalRule('number',$token+2,1) && &ALF_LexicalRule('arithmetic_value',$token+2,1) && $ALF_ParserData[$token+3] eq ';' && ($object = &ALF_CreateObject($parent,$type,0,$token+2)) && $token+3 || &ALF_SyntaxError('rotate',$token) ); } sub ALF_flip { local($token,$parent) = @_; local ($object,$type); $type = $ALF_ParserData[$token]; &StringMatch($type,'FLIP') && ( $ALF_ParserData[$token+1] eq '=' ### Errata: number should be arithmetic_value ### && &ALF_LexicalRule('number',$token+2,1) && &ALF_LexicalRule('arithmetic_value',$token+2,1) && $ALF_ParserData[$token+3] eq ';' && ($object = &ALF_CreateObject($parent,$type,0,$token+2)) && $token+3 || &ALF_SyntaxError('flip',$token) ); } sub ALF_repeat { local($token,$parent) = @_; local ($object,$type,$value); $type = $ALF_ParserData[$token]; $value = $ALF_ParserData[$token+2] if $ALF_ParserData[$token+1] eq '='; &StringMatch($type,'REPEAT') && ( ($object = &ALF_CreateObject($parent,$type,0,$value)) ### Errata: unsigned_integer should be arithmetic_value ### && &ALF_LexicalMatch('unsigned_integer',$value) && &ALF_LexicalMatch('arithmetic_value',$value) && ($token = $value? $token+3 : $token+1) && &ALF_SyntaxItems('geometric_transformation',$token,$object) || &ALF_SyntaxError('repeat',$token) ); } ################### ### Clause 9.19 ## ################### ### reference by order not yet implemented sub ALF_artwork { local($token,$parent) = @_; local ($object,$type,$value); $type = $ALF_ParserData[$token]; &StringMatch($type,'ARTWORK') && ( ($object = &ALF_CreateObject($parent,$type)) && ( $ALF_ParserData[$token+1] eq '=' && ($ALF_Value{$object} = $ALF_ParserData[$token+2]) && ( $ALF_ParserData[$token+3] eq ';' && $token+3 || &ALF_artwork_reference($token+2,$parent,$object) ) || &ALF_SyntaxItems('artwork_reference',$token+1,$parent) ) || &ALF_SyntaxError('artwork',$token) ); } ### Note: pin_assignement is an implicit interpretation ### within the syntax rule for artwork_reference ### See also clause 9.3 sub ALF_artwork_reference { local($token,$parent,$object) = @_; &ALF_LexicalRule('identifier',$token) || &ALF_SyntaxError('artwork_reference',$token); unless (defined($object)) { $type = $ALF_ParserData[$token]; $object = &ALF_CreateObject($parent,$type); } ($token = &ALF_SyntaxItems('geometric_transformation',$token,$object,0,1)) && &ALF_SyntaxItems('pin_assignment',$token+1,$object,1,0) || &ALF_SyntaxError('artwork_reference',$token+1); } ################### ### Clause 9.20 ## ################### sub ALF_via_instantiation { local($token,$parent) = @_; local ($object,$type,$name); $type = $ALF_ParserData[$token]; $name = $ALF_ParserData[$token+1]; &ALF_SyntaxMatch('via_instantiation',&UpperCase($type),$parent) && ( ($object = &ALF_CreateObject($parent,$type)) && &ALF_SyntaxItems('geometric_transformation',$token+2,$object) || &ALF_SyntaxError('via_instantiation',$token) ); } 1;