view src/luan/modules/parsers/Csv.java @ 1716:b82767112d8e

add String.regex
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 24 Jul 2022 23:43:03 -0600
parents b89212fd04b5
children
line wrap: on
line source

package luan.modules.parsers;

import luan.Luan;
import luan.LuanTable;
import luan.LuanException;
import goodjava.parser.Parser;
import goodjava.parser.ParseException;


public final class Csv {

	public static LuanTable toList(String line) throws ParseException {
		try {
			return new Csv(line).parse();
		} catch(LuanException e) {
			throw new RuntimeException(e);
		}
	}

	private final Parser parser;

	private Csv(String line) {
		this.parser = new Parser(line);
	}

	private ParseException exception(String msg) {
		return new ParseException(parser,msg);
	}

	private LuanTable parse() throws ParseException, LuanException {
		LuanTable list = new LuanTable();
		while(true) {
			Spaces();
			String field = parseField();
			list.rawPut(list.rawLength()+1,field);
			Spaces();
			if( parser.endOfInput() )
				return list;
			if( !parser.match(',') )
				throw exception("unexpected char");
		}
	}

	private String parseField() throws ParseException {
		parser.begin();
		String rtn;
		if( parser.match('"') ) {
			int start = parser.currentIndex();
			do {
				if( parser.endOfInput() ) {
					parser.failure();
					throw exception("unclosed quote");
				}
			} while( parser.noneOf("\"") );
			rtn = parser.textFrom(start);
			parser.match('"');
		} else {
			int start = parser.currentIndex();
			while( !parser.endOfInput() && parser.noneOf(",") );
			rtn = parser.textFrom(start).trim();
		}
		return parser.success(rtn);
	}

	private void Spaces() {
		while( parser.anyOf(" \t") );
	}

}