lvalue
). Por ejemplo en Kernighan y Ritchie C (KR C)
[11]
la asignación f(2,x) = 4
no es correcta pero si podría
serlo *f(2,x) = 4
.
En KR C las reglas
de producción que definen la parte izquierda de una asignación
(lvalue
) son mas complejas que las de SimpleC, especialmente
por la presencia de punteros:
Resumen de la Gramática de Kernighan y Ritchie C (KR C) en Parse::Eyapp | |
Expresiones | Declaraciones |
lvalue: identifier | primary '[' exp ']' | lvalue '.' identifier | primary '->' identifier | '*' exp | '(' lvalue ')' primary: identifier | constant | string | (exp) | primary '(' exp <*, ','> ')' | primary '[' exp ']' | lvalue '.' identifier | primary '->' identifier exp: primary | '*' exp | '&' exp | lvalue ASGNOP exp .......................... |
fund: t? dec '(' pr <* ','> ')' fb declaration: scty * (dec ini) <* ','> scty: scope | t scope: tdef | ... t: char | int | double | tdef_name ................... dec: identifier | '(' dec ')' | '*' dec | dec '(' ')' | dec '[' cexp ? ']' ini: '=' exp | '=' '{' exp <* ','> ','? '}' |
ASSIGN
pasa
a ser ASSIGNINT
o ASSIGNCHAR
según sea el tipo de la asignación.
De este modo eliminamos la sobrecarga semántica del nodo y
hacemos explícito en el nodo el tipo de asignación. Poco a poco nos vamos acercando
a niveles mas bajos de programación.
Sigue el código de comprobación para las asignaciones:
pl@nereida:~/doc/casiano/PLBOOK/PLBOOK/code/Simple-Types/lib/Simple$ \ sed -ne '/^assign/,180p' Trans.trg | cat -n 1 assign: /ASSIGN 2 |PLUSASSIGN 3 |MINUSASSIGN 4 |TIMESASSIGN 5 |DIVASSIGN 6 |MODASSIGN 7 /:asgn($lvalue, $exp) 8 => { 9 my $lt = $lvalue->{t}; 10 $exp = char2int($asgn, 1) if $lt == $INT; 11 $exp = int2char($asgn, 1) if $lt == $CHAR; 12 13 type_error("Incompatible types in assignment!", $asgn->line) 14 unless ($lt == $exp->{t}); 15 16 type_error("The C language does not allow assignments to non-scalar types!", $asgn->line) 17 unless ($lt == $INT) or ($lt == $CHAR); # Structs will also be allowed 18 19 # Assignments are expressions. Its type is the type of the lhs or the rhs 20 $asgn->{t} = $lt; 21 22 # Make explicit the type of assignment, i.e. s/PLUSASSIGN/PLUSASSIGNINT/ 23 $asgn->type(ref($asgn).ref($lt)); 24 25 return 1; 26 }
Veamos un ejemplo de comprobación de tipos en asignaciones:
pl@nereida:~/Lbook/code/Simple-Types/script$ usetypes.pl prueba12.c 2 1 int a,b[10][20],e[10][20]; 2 3 int f(char c) { 4 e[5] = b[5]; 5 a = b[1][2]; 6 } 7 Type Error at line 4: The C language does not allow assignments to non-scalar types!