Search code examples
jflex

Can't get JFlex output to compile


I have to make a compiler for a subset of C and I decided to use JFlex and Cup. However, when I create my .jflex file, it compiles fine with JFlex, but the output (.java file) will not compile.

Directory:

src:
    Lexer.java
    makefile
    jflex.jar
    cup.jar
    tinyc.jflex

So the command I execute are the follwing:

jflex tinyc.jflex
javac -cp ".:cup.jar:jflex.jar" Lexer.java

I keep getting the following errors:

Lexer.java:640: error: cannot find symbol
          { return new symbol(sym.NOT);
                       ^
  symbol:   class symbol
  location: class Lexer

Lexer.java:640: error: cannot find symbol
          { return new symbol(sym.NOT);
                              ^
  symbol:   variable sym
  location: class Lexer

Basicly it doesn't know the sym class, I suppose. I'm trying to get a basic version working by following examples but I just don't manage. Any pointers?

Edit:

I typed the example from the JFlex manual and tried to compile that one but it's giving me the same errors as well. So I must be doing something wrong. Any pointers?

tinyc.jflex:

import java_cup.runtime.*;
import java.io.FileInputStream;
import java.io.InputStream;



%%
%class Lexer
%cup
%line
%column
%unicode

%{
  StringBuffer string = new StringBuffer();

  private Symbol symbol(int type) {
    return new Symbol(type, yyline, yycolumn);
  }

  private Symbol symbol(int type, Object val) {
    return new Symbol(type, yyline, yycolumn, val);
  }

%}

digit       =  [0-9]
alpha       =  [a-zA-Z_]
alphanum    =  [A-Za-z0-9]
symbol      =  [_]
identifier  =  {alpha}+({alphanum}|{symbol})*

sl_comment  =  "//".*
ml_comment  =  "/*"((.*?)|[\n]*)*"*/"
commment    =  {sl_comment} | {ml_comment}

%%
"int"                   { return new symbol(sym.INTEGER);}
"char"                  { return new symbol(sym.CHAR);}
"return"                { return new symbol(sym.RETURN);}
"if"                    { return new symbol(sym.IF); }
"else"                  { return new symbol(sym.ELSE); }
"while"                 { return new symbol(sym.WHILE); }
"do"                    { return new symbol(sym.DO); }
"length"                { return new symbol(sym.LENGTH); }
"write"                 { return new symbol(sym.WRITE); }
"read"                  { return new symbol(sym.READ); }

","                     { return new symbol(sym.COMMA); }
";"                     { return new symbol(sym.SEMICOLON); }

"+"                     { return new symbol(sym.ADD); }
"-"                     { return new symbol(sym.MIN); }
"*"                     { return new symbol(sym.MUL); }
"/"                     { return new symbol(sym.DIV); }
"("                     { return new symbol(sym.LPAR); }
")"                     { return new symbol(sym.RPAR); }
"["                     { return new symbol(sym.LRBACK); }
"]"                     { return new symbol(sym.RBACK); }
"{"                     { return new symbol(sym.LBRACE); }
"}"                     { return new symbol(sym.RBRACE); }


">"                     { return new symbol(sym.GREATER); }
"<"                     { return new symbol(sym.LESS); }
"!="                    { return new symbol(sym.NEQ); }
"=="                    { return new symbol(sym.EQU); }

"!"                     { return new symbol(sym.NOT); }
"="                     { return new symbol(sym.ASSIGN); }

{identifier}            { return new symbol(sym.NAME, yytext());    }
{digit}+                { return new symbol(sym.NUMBER, new Integer(Integer.parseInt(yytext()))); }

{commment}              { yyline += countLines(yytext()); }

[\n]                    { ++yyline; }
[\r\t\f\ ]+             {  }
.                       { System.err.println("unexpected char " + yytext() + " !\n"); System.exit(0); }

Solution

  • The sym class is generally generated by CUP, not by JFlex. The symbols in the generated class are based off all of the terminals you define in your .cup file. To be able to use the sym class, you'll either have to make the .cup file with all of the appropriate symbols, or just make the class manually for the time being.