1 / 10

Using a Single Type of Semantic Value for Nonterminals and Terminals

Using a Single Type of Semantic Value for Nonterminals and Terminals. Semantic values for nonterminals are constructed from the semantic values of other grammar symbols.

karan
Download Presentation

Using a Single Type of Semantic Value for Nonterminals and Terminals

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Using a Single Type of Semantic Valuefor Nonterminals and Terminals • Semantic values for nonterminals are constructed from the semantic values of other grammar symbols. • arithmetic_expression : arithmetic_expression '+' term { $$ = new ASTMethodCall($1, $2, new ASTArgListSimple($3)); } • If the type of all semantic values is ASTNode *, then the constructor for ASTMethodCall must be declared as follows: • ASTNode *ASTMethodCall(ASTNode *rcvr, ASTNode *op, ASTNode *args) • Alternatively, one could downcast the arguments to the more specific types: • ASTNode *ASTMethodCall(ASTExpression *rcvr, ASTIdentifier *op, ASTArgList *args) • $$ = new ASTMethodCall(dynamic_cast<ASTExpression*>($1), dynamic_cast<ASTIdentifier*>$2, new ASTArgListSimple($3));

  2. Using Multiple Types of Semantic Valuefor Nonterminals and Terminals • To get a better handle on semantic value type, determine the collection of types that can be used as semantic values and use the bison %union construct to list these: • %union { ASTExpressionList *ExpressionList; ASTExpression *Expression; ASTAssignment *Assignment; ASTIdentifier *Identifier; ...} • Declare a bison %type for each nonterminal and terminal in your grammar • %type <Expression> factor;%type <Identifier> operator;%type <Identifier> IDENTIFIER_TOKEN; • Then each of the semantic values referenced through $1, ... $n, $$ will be declared to have the appopriate type and type-specific constructors can be used.

  3. Project Questions • What is the relation of GarnetObjects to ASTNodes? • Your parser actions will create ASTNodes • When you call eval on the whole program AST Node, you will create GarnetObjects. • start: expression_sequence { $1->ASTPrint(cout); // while debugging $1->eval(); } // to eval the whole program ; expression_sequence: ... • Do we have to implement Arrays in our program? • You will need to have Array GarnetObjects so that you can call methods with multiple arguments. • You do not need to support input of array literals, but it is practically free once you’ve implemented them • factor : ... | ‘[‘ arglist ‘]’ ...

  4. Project Questions • What is the structure of our referencing environment? • You only need to implement a single global frame. • Your frame must contain some representation of the mapping of variable names to their values. I suggest you use a Standard Template Library map for this purpose. In Garnet, each object has a type (its class), no name has a type. • What methods does each built-in class have to contain? • Object: print • Integer: to_s, +, -, !, *, /, <, >, <=, >=, == • Float : to_s, +, -, !, *, /, <, >, <=, >=, == • String: to_s • Array: get_element, set_element, to_s • Method: dispatch, to_s • Class: new, superclass, lookup_method, to_s • TrueClass: to_s, ! • FalseClass: to_s, ! • NilClass: to_s, !

  5. Further Project Questions • What about all that stuff Ashish was asking? • Use this grammar rule for your factors (or something similar) and I think you’ll be happy: • factor : identifier | '[' arglist ']' | INTEGER_TOKEN | FLOAT_TOKEN | factor '(' arglist') '| factor '.' operator /* make some ASTNode subclass for this */ | factor '[' expression '] ' | '(' expression ')' { $$ = $2; } ;operator: identifier | '+' | '-' | '*' | '/' ... ;

  6. : : superclass method_names myclass method_objects slots instance_slot_names Garnet Object Representations and the Class Hierarchy Class The Integer 1 Object Integer “+” String (Class) 1 Method (Class) code for +

  7. How do we represent all those Objects? • Here’s my declaration of the GarnetObject Class: • class GarnetObject {private: GarnetObject *myclass; vector<GarnetPtr> slotsvec; GarnetObject(const GarnetObject& init);public: GarnetObject(); GarnetObject(GarnetObject *cls, vector<GarnetPtr> slots); const GarnetObject& operator= (const GarnetObject& rhs);static void do_init();};

  8. What is a GarnetPtr? • I’ve relented and am now making the GarnetPtr a poor man’s implementation of a discriminated union. Here’s the discriminant type: • typedef enum { d_none, d_gptr, d_strptr, d_intval, d_floatval, d_funcptr }GarnetPtrDiscriminator; • Here’s a union type that matches this discriminant • typedef GarnetPtr (*MethodPtr)(GarnetPtr,GarnetPtr);typedef union { GarnetObject *gptr; string *strptr; int intval; double floatval; MethodPtr funcptr;} primitive;

  9. This is a GarnetPtr • Here’s the GarnetPtr class in all its glory: • class GarnetPtr {private: GarnetPtrDiscriminator d; primitive u;public: GarnetPtr(); GarnetPtr(const GarnetPtr &init); GarnetPtr& operator= (const GarnetPtr &rhs); GarnetPtr(GarnetObject *arg); GarnetPtr(string *arg); GarnetPtr(int arg); GarnetPtr(double arg); GarnetPtr(MethodPtr arg); GarnetObject *gp() const; string *sp() const; int iv() const; double fv() const; MethodPtr fp() const;};

  10. How about the GarnetPtr Constructors and Selectors • The constructors set the discriminant: • GarnetPtr::GarnetPtr(string *arg){ d = d_strptr; u.strptr = arg;} • The selectors query the discriminant: • void discriminant_error(GarnetPtrDiscriminator d1, GarnetPtrDiscriminator d2){ cerr << "Discriminant Error: expected " << d1 << ", got " << d2 << endl; exit(255);}string *GarnetPtr::sp() const{ if (d != d_strptr) { discriminant_error(d_strptr, d); } return u.strptr;}

More Related