2015-10-21 2 views
0

Я хотел бы закодировать CSVReader State Machine в ragel, так как я уже поступил на Java на Java с Enums. Возвращаемый список должен быть [a, b, c], но я получаю [nulla, b]. Я использую Ragel 6.8 на Fedora 22, я действительно надеюсь, что кто-нибудь может помочь мнеВыходы Ragel Java [nulla, b] вместо [a, b, c]

Это источник:

%%{ 

machine csv_reader_java; 
seperator = (';'|','); 
letter = [A-Za-z0-9]*; 

main := |* 
seperator => { putToList(tokens, string); }; 
letter => { emit(data, tokens, ts, te); }; 
space; 
*|; 

}%% 

import java.util.*; 

public class CSVReader { 

private String string; 

public void emit(char[] data, List<String> tokens, int ts, int te) { 
    char output = data[ts]; 
    string += output; 
} 
public void putToList(List<String> tokens, String data){ 
tokens.add(data); 
string = ""; 
} 

%% write data; 

public List<String> split(char[] data) { 
    int cs; /* state number */ 
    int p = 0, /* start of input */ 
    pe = data.length, /* end of input */ 
    eof = pe, 
    ts, /* token start */ 
    te, /* token end */ 
    act /* used for scanner backtracking */; 

    List<String> tokens = new ArrayList<String>(); 

    %% write init; 
    %% write exec; 

    return tokens; 
} 

public static void main(String[] args) { 
    System.out.println(new CSVReader().split("a,b,c".toCharArray())); 
} 
} 

И это то, что она возвращает меня: [nulla, b]

ответ

0

Перебирая это, я вижу две проблемы. Первый - это нуль в начале вашего вывода, который, как мне кажется, вызван не инициализацией string, когда начинается синтаксический анализ, который оставляет его null. Когда звонок emit достигает string += output;, string - null, поэтому он добавляет текущий токен («a») к строковому представлению null, в результате чего «nulla». Инициализация string с "" исправит это.

Вторая проблема, которая не добавляет «c» в список, еще проще. Значки только добавляются в список при обнаружении разделителя, и поскольку после «c» нет разделителя, этот токен не добавляется. Вы можете решить это, вызвав действие в конце файла на emit текущую строку токена, если она не пуста.

+0

хороший, это почти все, что мне нужно :-) –