Compiler Development Series--ocelot language 5. Validity check of expressions

Source: Internet
Author: User

This article examines "1=3" and "&5" for an incorrect expression that cannot be evaluated.

The following questions will be checked.
Assigning values to an expression that cannot be assigned (example: 1 = 2 + 2)
Calling a function using an illegal function name (example: "String" ("%d\n", I))
Invalid operand array Reference (example: 1[0])
Invalid operand member reference (example: 1.MEMB)
Pointer indirect reference with invalid operand (example: 1->MEMB)
To value a non-pointer object (example: *)
Address to a non-lvalue expression

Specific examples and the detection of the problem are shown in table 10.1, which includes the questions just listed.

Check for non-pointer type value operations

    /* Check for a non-pointer type value Operation     * represents the handling of the dereferencenode of the value operator (*).     * This method checks whether the type of the operand of the value operator is a pointer.     *    ///#@ @range/dereferencenode{public    Void visit (dereferencenode node) {/     * * First, through Super.visit (node) calls the base class visitor method traversal operand (node.expr ()) (that is, check the operand).     *        /super.visit (node);         /* Next, call the Ispointer method of the operand node.expr () to check whether the type of the operand is a pointer, that is, to check whether the value can be taken. If the value cannot be evaluated, the Undereferableerror method output compilation error is called.         *        /if (! node.expr (). Ispointer ()) {            undereferableerror (node.location ());        }         /* * Finally, call the Handleimplicitaddress method to deal specifically with array types and function types. This treatment is also related to the next addressnode processing,         *        /handleimplicitaddress (node);        return null;    }

Get check for non-lvalue expression address

    /* Get a check for non-lvalue expression addresses * Check if the operand is an lvalue. The processing of the addressnode that represents the address operator *//#@ @range/addressnode{public Void visit (addressnode node) {super.visit (nod        e); /* * First Call the Islvalue method on node.expr () to check if expr in &expr is an expression that can be taken.         Exprnode#islvalue is a method that checks whether an expression on that node can get an address.        */if (! node.expr (). Islvalue ()) {Semanticerror (Node.location (), "Invalid expression for &"); The remaining statements are used to determine the type of addressnode. usually node.expr (). Isloadable () returns True, which is the process of performing the else part.         The type of &expr is a pointer to the type of expr, so pointer types that point to node.expr (). Type () can be used as the type of the node as a whole.        */Type base = node.expr (). Type (); /* * When you set the type of puts to a pointer to a function, you must also set the type of &puts to a pointer to the function.         The type of node.expr () is specifically handled in the case of arrays or functions, making the type of &puts consistent with the type of puts.            */if (! node.expr (). Isloadable ()) {//Node.expr.type is already pointer.        Node.settype (base);        } else {Node.settype (Typetable.pointerto (base)); } return Null }

Implicit pointer-generation

A variable of a single array type or function type represents the address of an array or function. For example, assuming that the type of the variable puts is a function type (commonly referred to as a function pointer), then puts and &puts get the same values.

         /* * The Handleimplicitaddress method converts an array type or function type to a pointer to an array or function type, which implicitly generates a pointer type.     */    private void Handleimplicitaddress (Lhsnode node) {        if (! node.isloadable ()) {            Type t = Node.type (); C8/>if (T.isarray ()) {                //int[4] ary; ary; should generate int*                Node.settype (Typetable.pointerto (T.basetype () ));            }            else {                Node.settype (Typetable.pointerto (t));}}}    

puts is a pointer to a function, so the result of its value operation *puts is the function type, but this is implicitly converted to a pointer to a function. *puts is still a pointer to a function, so it can still be evaluated for operation and will still be converted to a pointer to a function. Like this can be indefinitely repeated. So the values of "&puts" "puts" "*puts" "**puts" "***puts" in C are the same.

Compiler Development Series--ocelot language 5. Validity check of expressions

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.