При использовании цикла for для создания массива объектов атрибуты верны внутри цикла, но неверны снаружи цикла - PullRequest
0 голосов
/ 23 октября 2018

Я хотел бы создать массив объектов, каждый из которых содержит три атрибута (правила, токены, приоритеты).

Для этого у меня есть один класс, который содержит все атрибуты в отдельных массивах (GenRules.java), и другой класс с конструктором для объекта (Token.java).

Воткакой-то код, который я выполняю, но обратите внимание, как выходные данные различаются в цикле for и вне цикла for:

public static void main( String[] args ) {

    // GenRules contains three arrays, one with the lexemes, another with their
    // corresponding tokens, and another with their priorities. They are separate
    // arrays but are related by index.
    int length = GenRules.length();

    // Generates an array of token objects containing all three attributes. 
    Token[] tok = new Token[ length ]; 
    for( int i = 0; i < length; i++ ) {
        tok[i] = Token.makeToken( GenRules.rules[i], 
                                  GenRules.tokens[i], 
                                  GenRules.priorities[i] );
        System.out.println( "i = " + i + ", " 
                                  + Token.getRule(tok[i]) + ", " 
                                  + Token.getToken(tok[i]) + ", " 
                                  + String.valueOf( Token.getPriority( tok[i] ) ) );
    }

    System.out.println( "\n" );
    int i = 0;
    for( Token t : tok ) {
        t = tok[i];
        System.out.println( "i = " + i + " " 
                + t.getRule(t) + " " 
                + t.getToken(t) + " " 
                + t.getPriority(t) );
        i++;
    }

}

Вывод, генерируемый внутри цикла for, - это то, что я ожидал бы увидеть:

i = 0, /\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/, COMMENT, -1
i = 1, d+, NUMBER, 60
i = 2, int, TYPE_INT, 60
i = 3, char, TYPE_CHAR, 5
i = 4, main, MAIN, -1
.
.
.
i = 21, (, LP, 40
i = 22, ), RP, 40
i = 23, ==, EQUALVALUE, 20
i = 24, =, EQUALSIGN, 30

Но вне цикла for, похоже, что все объекты инициализируются с одинаковыми тремя атрибутами:

i =  0 = EQUALSIGN 30
i =  1 = EQUALSIGN 30
i = 02 = EQUALSIGN 30
.
.
.
i = 22 = EQUALSIGN 30
i = 23 = EQUALSIGN 30
i = 24 = EQUALSIGN 30

Есть идеи, где я ошибаюсь?Для полноты я добавлю два других нижеприведенных класса, пожалуйста, не стесняйтесь вязать в любом общем коде, который вы не видите.

GenRules.java

package src;

/**
 * @author 
 * <p>
 * This class defines all of the lexing rules and tokens and has some helper functions to 
 * figure out how many rules currently exist. The arrays and values can be accessed statically, ie, no 
 * need to initialize a GenRules object. If the priority of a lexeme is 'None' it will return a '-1'. 
 * </p>
 */

public class GenRules {

/**
 * Regex comparison to a given token.
 */
public static String[] rules = { // 25 rules
        "/\\*([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*+/"        ,
        "d+"  ,"int","char","main"                       ,"return",
        "else","if" ,"for" ,"[_a-zA-Z][_a-zA-Z0-9]{0,31}","{"     ,
        "}"   ,";"  ,"<="  ,"<"                          ,">="    ,
        ">"   ,"+"  ,"-"   ,"*"                          ,"/"     ,
        "("   ,")"  ,"=="  ,"="
        };  

/**
 * Token issued to token at corresponding index.
 */
public static String[] tokens = { // 25 tokens
        "COMMENT"         ,"NUMBER"     ,"TYPE_INT" ,"TYPE_CHAR"    ,"MAIN",
        "RETURN"          ,"ELSE"       ,"IF"       ,"FOR"          ,"IDENTIFIER",
        "LB"              ,"RB"         ,"SEMICOLON","LESSTHANEQUAL","LESSTHAN",
        "GREATERTHANEQUAL","GREATERTHAN","PLUS"     ,"MINUS"        ,"MULTIPLY",
        "DIVIDE"          ,"LP"         ,"RP"       ,"EQUALVALUE"   ,"EQUALSIGN"
        };

/**
 * Priority issued to a corresponding token. 
 */
public static int[] priorities = { // 25 priorities
        -1,60,60, 5,-1,
        5 ,10,10,10, 8,
        9 ,10,70,20,20,
        20,20,70,70,65,
        65,40,40,20,30 
        };

/**
 * Prints how may tokens are currently defined. If there is a mismatch in how
 * many tokens there are in comparison to priorities or rules it will return '0'.
 */
public static int length() {
    if( priorities.length == tokens.length && tokens.length == rules.length )
        return rules.length;
    else return 0;
}

/**
 * Returns all of the rules components in array form.
 */
public static String[] returnRules() {
    return rules;

}

/**
 * Returns all of the token components in array form.
 */
public static String[] returnTokens() {
    return tokens;

}

/**
 * Returns all of the priorities in array form.
 */
public static int[] returnPriorities() {
    return priorities;

}

/**
 * Prints the rule followed by token, followed by priority. Isn't formatted very well. 
 */
public static String printRules(  ) {
    String out = "";
    for( int i = 0; i < priorities.length; i++ ) {
        out += rules[i] + " " + tokens[i] + " " + String.valueOf( priorities[i] ) + "\n";
    }
    return out;
}

}

Token.java:

package src;

/**
 * @author 
 *<p>
 *This class takes the rules, tokens, and priorities described in the GenRules
 *class and encapsulates them in a single object. A token can be thought of like
 *a struct which contains one rule, one token, and one priority level.
 *</p>
 */
public class Token {

private static String rule;
private static String token;
private static int priority;

public Token() {
    // Empty like my heart.
}

/**
 * Constructor; applies values to the class attributes. 
 * @param s1 rule
 * @param s2 token
 * @param i priority
 */
public Token( String s1, String s2, int i ) {
    rule = s1;
    token = s2;
    priority = i;
}

/**
 * Takes in arguments to construct a token and generates one
 * using the constructor. Once generated it is returned to 
 * wherever it was called from. 
 * @param s1
 * @param s2
 * @param i
 * @return Returns a formed token object.
 */
public static Token makeToken( String s1, String s2, int i ) {
    Token t = new Token( s1, s2, i );
    return t;
}

/**
 * Returns the rule from a Token.
 * @param t
 * @return
 */
public static String getRule( Token t ) {
    return t.rule.toString();
}

/**
 * Returns the 'token' from a Token.
 * @param t
 * @return
 */
public static String getToken( Token t ) {
    return t.token.toString();
}

/**
 * Returns the priority value from a Token.
 * @param t
 * @return
 */
public static String getPriority( Token t ) {
    return String.valueOf( t.priority );
}

/**
 * Will print out the rule, token, and priority values given
 * an array of tokens. 
 * @param t
 */
public static void printTokens( Token[] ti ) {
    for( Token t : ti ) {
        System.out.print( t.getRule( t ) + " " );
        System.out.print( t.getToken( t ) + " " );
        System.out.print( t.getPriority( t ) + "\n" );
    }
}

} ​​

1 Ответ

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

Ваши переменные в классе Token static, поэтому они принадлежат классу, а не каждому отдельному объекту Token.Каждый раз, когда вы устанавливаете эти переменные, оно перезаписывает последнее значение (поэтому всегда печатает последние присвоенные значения).

private static String rule;
private static String token;
private static int priority;

Удалите ключевое слово static и повторите попытку.

private String rule;
private String token;
private int priority;
...