Объект успешно добавлен в Java ArrayList, но при попытке получить этот ArrayList возвращает пустой список - PullRequest
0 голосов
/ 14 октября 2018

Я пишу спецификацию лексера для Jflex, которая должна прочитать входной файл и вернуть токен.Я успешно завершаю эту часть, как показано ниже:

    /*Super-FORTAN language lexer specification*/
%%
%public
%class LexicalAnalyser
%unicode
%line
%column
%type Symbol
%standalone

%{
  private ArrayList<Symbol> tokens = new ArrayList<Symbol>();

  public LexicalAnalyser() {
    //ArrayList<Symbol> tokens = new ArrayList<Symbol>();
  }

  /**
  * This method will be called as action to be taken in the rules and actions section
  * of the lexer.
  * @para  m unit the lexical unit of the lexer
  * @param value the matched input characters
  * @return return an object of type symbol
  *
  */

  public Symbol symbol(LexicalUnit unit, Object value){
    Symbol token = new Symbol(unit, yyline+1, yycolumn+1, value);

    if(token != null) {
      tokens.add(token);  //add a token to the token list
      //System.out.println("Token added && the size is: " + tokens.size()); //Checking whether a token has been successfully added
    } else{
      System.out.println("Failed to add token");
    }

    System.out.println(token); //print out the list of token to standard output
    return  token;
  }

  public ArrayList<Symbol> getTokens(){
    System.out.println("In total " + tokens.size() + " tokens have been found");
    return tokens;
  }

  public boolean isZzAtEOF() {
    return zzAtEOF;
  }
  %}

  %eofval{
    return new Symbol(LexicalUnit.EOS, yyline, yycolumn);
    %eofval}

    /*Program Name */
    ProgramName = [:uppercase:][:jletterdigit:]*[:lowercase:][:jletterdigit:]*

    /*Variables names*/
    VarName = [:lowercase:][a-z0-9]*

    /*Carriage Return*/
    EndLine = \r|\n|\r\n

    /*Number*/
    Number = [1-9][0-9]*

    EOS = {EndLine} | [\t\f\b]

    /*Input character*/
    InputCharacter = [^\r|\n]

    /*Comments*/
    Shortcomment ="//"{InputCharacter}*{EndLine}?
    Longcomment = "/*"[^'*']~"*/"
    Comment = {Shortcomment}|{Longcomment}
    FileMetaData ="rtf1"~"cf0 "

    %state STRING, CHARLITERAL
    %%

    <YYINITIAL> {
      /*Program Name*/
      {ProgramName} {return symbol(LexicalUnit.PROGNAME, yytext());}

      /* keywords */
      "BEGINPROG" {return symbol(LexicalUnit.BEGINPROG, yytext());
      }
      "DO" {return symbol(LexicalUnit.DO, yytext());}
      "ENDPROG"   {return symbol(LexicalUnit.ENDPROG, yytext());}
      "ENDIF"  {return symbol(LexicalUnit.ENDIF, yytext());}
      "ENDFOR" {return symbol(LexicalUnit.ENDFOR, yytext());}
      "ENDWHILE" {return symbol(LexicalUnit.ENDWHILE, yytext());}
      "ELSE" {return symbol(LexicalUnit.ELSE, yytext());}
      "FOR" {return symbol(LexicalUnit.FOR, yytext());}
      "IF" {return symbol(LexicalUnit.IF, yytext());}
      "PRINT" {return symbol(LexicalUnit.PRINT, yytext());}
      "THEN" {return symbol(LexicalUnit.THEN, yytext());}
      "TO" {return symbol(LexicalUnit.TO, yytext());}
      "READ"  {return symbol(LexicalUnit.READ, yytext());}
      "VARIABLES" {return  symbol(LexicalUnit.VARIABLES, yytext());}

      /*Binary operators */
      "AND"   {return symbol(LexicalUnit.AND, yytext());}
      "OR"    {return symbol(LexicalUnit.OR, yytext());}

      /*operators */
      "+"  {return symbol(LexicalUnit.PLUS, yytext());}
      "-"  {return symbol(LexicalUnit.MINUS, yytext());}
      "*"  {return symbol(LexicalUnit.TIMES, yytext());}
      "/"  {return symbol(LexicalUnit.DIVIDE, yytext());}

      /*Comparator */
      "="  {return symbol(LexicalUnit.EQ, yytext());}
      ">=" {return symbol(LexicalUnit.GEQ, yytext());}
      ">"  {return symbol(LexicalUnit.GT, yytext());}
      "<=" {return symbol(LexicalUnit.LEQ, yytext());}
      "<"  {return symbol(LexicalUnit.LT, yytext());}
      "NOT" {return symbol(LexicalUnit.NOT, yytext());}
      "<>" {return symbol(LexicalUnit.NEQ, yytext());}

      /* separators */
      {EndLine} {return new Symbol(LexicalUnit.ENDLINE, yyline, yycolumn);}
      "(" {return symbol(LexicalUnit.LPAREN, yytext());}
      ")" {return symbol(LexicalUnit.RPAREN, yytext());}
      "," {return symbol(LexicalUnit.COMMA, yytext());}

      /*Assignment */
      ":=" {return symbol(LexicalUnit.ASSIGN, yytext());}

      /*identifiers*/
      {VarName} {return symbol(LexicalUnit.VARNAME, yytext());}

      /*numbers */
      {Number} {return symbol(LexicalUnit.NUMBER, yytext());}

      {Comment} {}
        {FileMetaData} {}
    }

Приведенная выше спецификация генерирует лексер, вызываемый при передаче его в качестве входных данных для Jflex.Проблема в том, что я создаю список массивов и пытаюсь добавить каждый символ в этот список, как показано ниже:

public Symbol symbol(LexicalUnit unit, Object value){
    Symbol token = new Symbol(unit, yyline+1, yycolumn+1, value);
    if(token != null) {
      tokens.add(token);  //add a token to the token list
      //System.out.println("Token added && the size is: " +   tokens.size()); //Checking whether a token has been successfully added
    } else{
      System.out.println("Failed to add token");
 }

Используя оператор print в этом методе, я подтверждаю, что каждый объект успешно добавлен.Однако, когда я вызываю getTokens () из моего основного класса (как показано ниже).Я получаю пустой список:

public class Main{
    /**
    * Runs the scanner on input files.
    *
    * This is a standalone scanner, it will print any unmatched
    * text to System.out unchanged.
    *
    * @param argv   the command line, contains the filenames to run
    *               the scanner on.
    */

    public static void main(String argv[]){
    LexicalAnalyser lexer = new LexicalAnalyser();

    lexer.main(argv);

    System.out.println("\nIdentifiers");

    ArrayList<Symbol> tokenList = lexer.getTokens(); //Retrieving the token list
    System.out.println("Token added && the size is: " + tokenList.size());

    for(Symbol tk: tokenList){
        if(tk !=null){
            if (tk.getType() == LexicalUnit.VARIABLES){
                System.out.println(tk.getValue() + " " + tk.getLine() );
            }
        }
    }
}

}

Я что-то упустил?единственный фрагмент кода, который я здесь не предоставляю, это класс объекта Symbol.Я хотел бы знать, какой момент я здесь скучаю.Большое вам спасибо.

1 Ответ

0 голосов
/ 14 октября 2018

Размер равен 0, потому что вы инициализировали новый экземпляр TokenList в своем основном классе и сделали цикл for для этого пустого экземпляра.
Вы добавляете токен в список токенов в своем классе LexicalAnalyser,который является частным, поэтому вы должны предоставить метод получения и получить его.

Добавьте это в ваш LexicalAnalyser класс:

public ArrayList<Symbol> getTokenList() {
    return tokens.getTokenList();
}

В основном классе измените tokenList = tokens.getTokenList(); на tokenList = lexer.getTokenList();

...