Universidad Tecnológica Centroamericana
        Ingeniería en Sistemas Computacionales
        Compiladores I
        Prof. Egdares Futch H.

                       CUP - Ejemplo complejo de uso, incluyendo JFlex y AST
Operator.java                             Pam.jlex
                                          %%
// Operator is an auxiliary class         %{
to define lexical token values for           private void echo () { System . out . print (yytext ()); }
// operators.
                                               private java_cup . runtime . Symbol token (int token_class,
class Operator {                                   Object token_value) {
                                                 return new java_cup . runtime . Symbol (token_class, yychar,
  // adding operators                              yychar + yylength (), token_value);
  public final static Integer PLUS             }
= new Integer ('+');                           private java_cup . runtime . Symbol token (int token_class) {
  public final static Integer MINUS              return new java_cup . runtime . Symbol (token_class, yychar,
= new Integer ('-');                               yychar + yylength (), null);
                                               }
  // multiplying operators                %}
  public final static Integer TIMES
= new Integer ('*');                      %function nextToken
  public final static Integer SLASH       %type     java_cup . runtime . Symbol
= new Integer ('/');                      %char
                                          %eofval{
  // relational operators                   { return token (Symbol . EOF); }
  public final static int   LT   =   0;   %eofval}
  public final static int   LE   =   1;
  public final static int   GT   =   2;   d = [0-9]
  public final static int   GE   =   3;   l = [A-Za-z]
  public final static int   EQ   =   4;
  public final static int   NE   =   5;   %%
                                          [ tn]        {    echo   ();   }
  // I/O operators                        ";"             {    echo   ();   return   token   (Symbol   .   SEMICOLON); }
  public final static Integer READ        ","             {    echo   ();   return   token   (Symbol   .   COMMA); }
= new Integer (10);                       "."             {    echo   ();   return   token   (Symbol   .   DOT); }
  public final static Integer WRITE       "<"             {    echo   ();   return   token   (Symbol   .   RELOP, new Integer
= new Integer (11);                       (Operator . LT));    }
}                                         "<="            {    echo   (); return token (Symbol . RELOP, new Integer
                                          (Operator . LE));    }
                                          ">"             {    echo   (); return token (Symbol . RELOP, new Integer
                                          (Operator . GT));    }
                                          ">="            {    echo   (); return token (Symbol . RELOP, new Integer
                                          (Operator . GE));    }
                                          "="             {    echo   (); return token (Symbol . RELOP, new Integer
                                          (Operator . EQ));    }
                                          "<>"            {    echo   (); return token (Symbol . RELOP, new Integer
                                          (Operator . NE));    }
                                          "("             {    echo   (); return token (Symbol . LEFTPAREN); }
                                          ")"             {    echo   (); return token (Symbol . RIGHTPAREN); }
                                          "+"             {    echo   (); return token (Symbol . ADDOP, Operator .
                                          PLUS); }
                                          "-"             {    echo (); return token (Symbol . ADDOP,              Operator .
                                          MINUS); }
                                          "*"             {    echo (); return token (Symbol . MULTOP, Operator .
                                          TIMES); }
                                          "/"             {    echo (); return token (Symbol . MULTOP, Operator .
                                          SLASH); }
                                          ":="            {    echo   ();   return   token   (Symbol   .   ASSIGN); }
                                          do              {    echo   ();   return   token   (Symbol   .   DO); }
                                          else            {    echo   ();   return   token   (Symbol   .   ELSE); }
                                          end             {    echo   ();   return   token   (Symbol   .   END); }
                                          fi              {    echo   ();   return   token   (Symbol   .   FI); }
                                          if              {    echo   ();   return   token   (Symbol   .   IF); }
                                          read            {    echo   ();   return   token   (Symbol   .   IO, Operator . READ); }
                                          then            {    echo   ();   return   token   (Symbol   .   THEN); }
                                          to              {    echo   ();   return   token   (Symbol   .   TO); }
                                          while           {    echo   ();   return   token   (Symbol   .   WHILE); }
                                          write           {    echo   ();   return   token   (Symbol   .   IO, Operator . WRITE); }
                                          {d}+            {    echo   ();   return   token   (Symbol   .   INTEGER, new Integer
                                          (yytext ())); }
                                          {l}({l}|{d})*   {    echo (); return token (Symbol . ID, yytext ()); }
// SyntaxTree.java                      parser code {:
                                          Yylex lexer;
// SyntaxTree is a class to
represent a node of a ternary             // Error handling function.
syntax tree.
                                          public void report_fatal_error (String message, Object info) {
class SyntaxTree {                          done_parsing ();
                                            System . out . println (message);
  private   String node;                    System . exit (1);
  private   SyntaxTree left;              }
  private   SyntaxTree middle;
  private   SyntaxTree right;             // This constructor assumes that the parser is named PamParser.

  // constructor functions                public PamParser (Yylex l) {
                                            this ();
  public SyntaxTree (String                 lexer = l;
node_value, SyntaxTree left_tree,         }
      SyntaxTree middle_tree,
SyntaxTree right_tree) {                :};
    node   = new String
(node_value);                           action code {:
    left   = left_tree;
    middle = middle_tree;                 java.util.Dictionary dict = new java.util.Hashtable();
    right = right_tree;
  }                                       Integer get(String id) {
                                                return((Integer)dict.get(id.intern()));
  public SyntaxTree () {                  }
    this ("", null, null, null);          void put(String id, int v) {
    node = null;                                dict.put(id.intern(), new Integer(v));
  }                                       }

  public SyntaxTree (String             :};
node_value) {
    this (node_value, null, null,       scan with {: return lexer . nextToken (); :};
null);
  }                                     terminal Integer INTEGER, RELOP, ADDOP, MULTOP, IO;
                                        terminal String ID;
  // selector functions                 terminal SEMICOLON, LEFTPAREN, RIGHTPAREN, COMMA, DOT, ASSIGN,
                                          DO, ELSE, END, FI, IF, THEN, TO, WHILE;
  public String root ()          {
return node; }                          non terminal SyntaxTree program, series, statement, else_option, id,
  public SyntaxTree left ()      {      id_list,
return left; }                            comparison, expression, term, factor;
  public SyntaxTree middle ()    {
return middle; }                        start with program;
  public SyntaxTree right ()     {
return right; }                         program ::= series:ser DOT {: RESULT = ser; :};

  // print prints the tree in           series ::= statement:st {: RESULT = st; :}
Cambridge Polish prefix notation.           | series:ser SEMICOLON statement:st {: RESULT = new SyntaxTree (";",
                                        ser, st); :};
  public void print () {
    System . out . println   ("");      statement ::= IO:io id_list:il
    System . out . println   ("Syntax           {: if (io == Operator . READ)
Tree");                                              RESULT = new SyntaxTree ("read", il);
    System . out . println   ("------              else
-----");                                             RESULT = new SyntaxTree ("write", il); :}
    System . out . println   ("");          | id:var ASSIGN expression:exp {: RESULT = new SyntaxTree (":=", var,
    printTree ();                       exp); :}
    System . out . println   ("");          | IF comparison:comp THEN series:then_ser else_option:else_ser FI
  }                                             {: RESULT = new SyntaxTree ("if", comp, then_ser, else_ser); :}
                                            | TO expression:exp DO series:ser END
                                                {: RESULT = new SyntaxTree ("to", exp, ser); :}
                                            | WHILE comparison:comp DO series:ser END
                                                {: RESULT = new SyntaxTree ("while", comp, ser); :}
                                            ;

                                        id ::= ID:id {: RESULT = new SyntaxTree ("id", new SyntaxTree (id)); :};

                                        id_list ::= id:i {: RESULT = i; :}
                                            | id_list:il COMMA id:i {: RESULT = new SyntaxTree (",", il, i); :};

                                        else_option ::= ELSE series:ser {: RESULT = ser; :}
                                            | {: RESULT = null; :};

                                        comparison ::= expression:exp1 RELOP:relop expression:exp2
                                                {: switch (relop . intValue ()) {
class Pam {                                        case Operator   . LT : RESULT = new SyntaxTree ("<",   exp1,
                                      exp2); break;
  public static void main (String                  case Operator   . LE : RESULT = new SyntaxTree ("<=", exp1,
args []) {                            exp2); break;
    PamParser parser;                              case Operator   . GT : RESULT = new SyntaxTree (">",   exp1,
    SyntaxTree syntax_tree;           exp2); break;
                                                   case Operator   . GE : RESULT = new SyntaxTree (">=", exp1,
    System . out . println ("Source   exp2); break;
Program");                                         case Operator   . EQ : RESULT = new SyntaxTree ("=",   exp1,
    System . out . println ("------   exp2); break;
--------");                                        case Operator   . NE : RESULT = new SyntaxTree ("<>", exp1,
    System . out . println ("");      exp2); break; } :};

    parser = new PamParser (new       expression ::= expression:exp ADDOP:addop term:t
Yylex (System . in));                         {: if (addop == Operator . PLUS)
    try {                                          RESULT = new SyntaxTree ("+", exp, t);
      syntax_tree = (SyntaxTree)                 else
parser . parse () . value;                         RESULT = new SyntaxTree ("-", exp, t); :}
      syntax_tree . print ();             | term:t {: RESULT = t; :};
      System . out . println ("");
      System . out . println          term ::= term:t MULTOP:multop factor:f
("Parse successful");                         {: if (multop == Operator . TIMES)
    }                                              RESULT = new SyntaxTree ("*", t, f);
    catch (Throwable e) {                        else
      e . printStackTrace ();                      RESULT = new SyntaxTree ("/", t, f); :}
      System . out . println (e);         | factor:f {: RESULT = f; :};
    }
  }                                   factor ::= LEFTPAREN expression:exp RIGHTPAREN {: RESULT = exp; :}
                                          | INTEGER:n
}                                             {: RESULT = new SyntaxTree ("integer", new SyntaxTree (n . toString
                                      ())); :}
                                          | id:i {: put(id, e.intValue()); RESULT = i; :};

Ejemplo completo de integración JLex y CUP

  • 1.
    Universidad Tecnológica Centroamericana Ingeniería en Sistemas Computacionales Compiladores I Prof. Egdares Futch H. CUP - Ejemplo complejo de uso, incluyendo JFlex y AST Operator.java Pam.jlex %% // Operator is an auxiliary class %{ to define lexical token values for private void echo () { System . out . print (yytext ()); } // operators. private java_cup . runtime . Symbol token (int token_class, class Operator { Object token_value) { return new java_cup . runtime . Symbol (token_class, yychar, // adding operators yychar + yylength (), token_value); public final static Integer PLUS } = new Integer ('+'); private java_cup . runtime . Symbol token (int token_class) { public final static Integer MINUS return new java_cup . runtime . Symbol (token_class, yychar, = new Integer ('-'); yychar + yylength (), null); } // multiplying operators %} public final static Integer TIMES = new Integer ('*'); %function nextToken public final static Integer SLASH %type java_cup . runtime . Symbol = new Integer ('/'); %char %eofval{ // relational operators { return token (Symbol . EOF); } public final static int LT = 0; %eofval} public final static int LE = 1; public final static int GT = 2; d = [0-9] public final static int GE = 3; l = [A-Za-z] public final static int EQ = 4; public final static int NE = 5; %% [ tn] { echo (); } // I/O operators ";" { echo (); return token (Symbol . SEMICOLON); } public final static Integer READ "," { echo (); return token (Symbol . COMMA); } = new Integer (10); "." { echo (); return token (Symbol . DOT); } public final static Integer WRITE "<" { echo (); return token (Symbol . RELOP, new Integer = new Integer (11); (Operator . LT)); } } "<=" { echo (); return token (Symbol . RELOP, new Integer (Operator . LE)); } ">" { echo (); return token (Symbol . RELOP, new Integer (Operator . GT)); } ">=" { echo (); return token (Symbol . RELOP, new Integer (Operator . GE)); } "=" { echo (); return token (Symbol . RELOP, new Integer (Operator . EQ)); } "<>" { echo (); return token (Symbol . RELOP, new Integer (Operator . NE)); } "(" { echo (); return token (Symbol . LEFTPAREN); } ")" { echo (); return token (Symbol . RIGHTPAREN); } "+" { echo (); return token (Symbol . ADDOP, Operator . PLUS); } "-" { echo (); return token (Symbol . ADDOP, Operator . MINUS); } "*" { echo (); return token (Symbol . MULTOP, Operator . TIMES); } "/" { echo (); return token (Symbol . MULTOP, Operator . SLASH); } ":=" { echo (); return token (Symbol . ASSIGN); } do { echo (); return token (Symbol . DO); } else { echo (); return token (Symbol . ELSE); } end { echo (); return token (Symbol . END); } fi { echo (); return token (Symbol . FI); } if { echo (); return token (Symbol . IF); } read { echo (); return token (Symbol . IO, Operator . READ); } then { echo (); return token (Symbol . THEN); } to { echo (); return token (Symbol . TO); } while { echo (); return token (Symbol . WHILE); } write { echo (); return token (Symbol . IO, Operator . WRITE); } {d}+ { echo (); return token (Symbol . INTEGER, new Integer (yytext ())); } {l}({l}|{d})* { echo (); return token (Symbol . ID, yytext ()); }
  • 2.
    // SyntaxTree.java parser code {: Yylex lexer; // SyntaxTree is a class to represent a node of a ternary // Error handling function. syntax tree. public void report_fatal_error (String message, Object info) { class SyntaxTree { done_parsing (); System . out . println (message); private String node; System . exit (1); private SyntaxTree left; } private SyntaxTree middle; private SyntaxTree right; // This constructor assumes that the parser is named PamParser. // constructor functions public PamParser (Yylex l) { this (); public SyntaxTree (String lexer = l; node_value, SyntaxTree left_tree, } SyntaxTree middle_tree, SyntaxTree right_tree) { :}; node = new String (node_value); action code {: left = left_tree; middle = middle_tree; java.util.Dictionary dict = new java.util.Hashtable(); right = right_tree; } Integer get(String id) { return((Integer)dict.get(id.intern())); public SyntaxTree () { } this ("", null, null, null); void put(String id, int v) { node = null; dict.put(id.intern(), new Integer(v)); } } public SyntaxTree (String :}; node_value) { this (node_value, null, null, scan with {: return lexer . nextToken (); :}; null); } terminal Integer INTEGER, RELOP, ADDOP, MULTOP, IO; terminal String ID; // selector functions terminal SEMICOLON, LEFTPAREN, RIGHTPAREN, COMMA, DOT, ASSIGN, DO, ELSE, END, FI, IF, THEN, TO, WHILE; public String root () { return node; } non terminal SyntaxTree program, series, statement, else_option, id, public SyntaxTree left () { id_list, return left; } comparison, expression, term, factor; public SyntaxTree middle () { return middle; } start with program; public SyntaxTree right () { return right; } program ::= series:ser DOT {: RESULT = ser; :}; // print prints the tree in series ::= statement:st {: RESULT = st; :} Cambridge Polish prefix notation. | series:ser SEMICOLON statement:st {: RESULT = new SyntaxTree (";", ser, st); :}; public void print () { System . out . println (""); statement ::= IO:io id_list:il System . out . println ("Syntax {: if (io == Operator . READ) Tree"); RESULT = new SyntaxTree ("read", il); System . out . println ("------ else -----"); RESULT = new SyntaxTree ("write", il); :} System . out . println (""); | id:var ASSIGN expression:exp {: RESULT = new SyntaxTree (":=", var, printTree (); exp); :} System . out . println (""); | IF comparison:comp THEN series:then_ser else_option:else_ser FI } {: RESULT = new SyntaxTree ("if", comp, then_ser, else_ser); :} | TO expression:exp DO series:ser END {: RESULT = new SyntaxTree ("to", exp, ser); :} | WHILE comparison:comp DO series:ser END {: RESULT = new SyntaxTree ("while", comp, ser); :} ; id ::= ID:id {: RESULT = new SyntaxTree ("id", new SyntaxTree (id)); :}; id_list ::= id:i {: RESULT = i; :} | id_list:il COMMA id:i {: RESULT = new SyntaxTree (",", il, i); :}; else_option ::= ELSE series:ser {: RESULT = ser; :} | {: RESULT = null; :}; comparison ::= expression:exp1 RELOP:relop expression:exp2 {: switch (relop . intValue ()) {
  • 3.
    class Pam { case Operator . LT : RESULT = new SyntaxTree ("<", exp1, exp2); break; public static void main (String case Operator . LE : RESULT = new SyntaxTree ("<=", exp1, args []) { exp2); break; PamParser parser; case Operator . GT : RESULT = new SyntaxTree (">", exp1, SyntaxTree syntax_tree; exp2); break; case Operator . GE : RESULT = new SyntaxTree (">=", exp1, System . out . println ("Source exp2); break; Program"); case Operator . EQ : RESULT = new SyntaxTree ("=", exp1, System . out . println ("------ exp2); break; --------"); case Operator . NE : RESULT = new SyntaxTree ("<>", exp1, System . out . println (""); exp2); break; } :}; parser = new PamParser (new expression ::= expression:exp ADDOP:addop term:t Yylex (System . in)); {: if (addop == Operator . PLUS) try { RESULT = new SyntaxTree ("+", exp, t); syntax_tree = (SyntaxTree) else parser . parse () . value; RESULT = new SyntaxTree ("-", exp, t); :} syntax_tree . print (); | term:t {: RESULT = t; :}; System . out . println (""); System . out . println term ::= term:t MULTOP:multop factor:f ("Parse successful"); {: if (multop == Operator . TIMES) } RESULT = new SyntaxTree ("*", t, f); catch (Throwable e) { else e . printStackTrace (); RESULT = new SyntaxTree ("/", t, f); :} System . out . println (e); | factor:f {: RESULT = f; :}; } } factor ::= LEFTPAREN expression:exp RIGHTPAREN {: RESULT = exp; :} | INTEGER:n } {: RESULT = new SyntaxTree ("integer", new SyntaxTree (n . toString ())); :} | id:i {: put(id, e.intValue()); RESULT = i; :};