0

我想用 ragel 编写一个 CSVReader 状态机,因为我已经用 Enums 用 Ja​​va 完成了我的工作。返回的列表应该是 [a,b,c] 但我得到 [nulla,b]。我在 Fedora 22 上使用 Ragel 6.8,我真的希望有人能帮助我

这是来源:

%%{

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]

4

1 回答 1

0

回顾一下,我发现了两个问题。第一个是输出开始时的 null ,我认为这是由于string在解析开始时未初始化造成的,因此它离开了它null。当emit调用到达string += output;, stringisnull时,它会将当前标记(“a”)附加到 的字符串表示中null,从而产生“nulla”。初始化string""解决此问题。

第二个问题,即不将“c”添加到列表中的问题,甚至更简单。只有在找到分隔符时才会将标记添加到列表中,并且由于“c”之后没有分隔符,因此不会添加该标记。emit如果当前令牌字符串不为空,您可以通过在文件末尾调用操作来解决此问题。

于 2016-01-05T02:49:14.913 回答