/*
*
* Copyright 2012 lexergen.
* This file is part of lexergen.
*
* lexergen is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lexergen is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with lexergen. If not, see <http://www.gnu.org/licenses/>.
*
* lexergen:
* A tool to chunk source code into tokens for further processing in a compiler chain.
*
* Projectgroup: bi, bii
*
* Authors: Benjamin Weißenfels
*
* Module: Softwareprojekt Übersetzerbau 2012
*
* Created: Apr. 2012
* Version: 1.0
*
*/
package de.fuberlin.bii.parsetokdef;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import de.fuberlin.bii.utils.IRule;
import de.fuberlin.bii.utils.Rule;
/**
* Liest zeichenweise eine Tokendefinitionsdatei ein. Weitere Information:
* {@linkplain https
* ://github.com/PascalCase/swp-uebersetzerbau-ss12/wiki/Lexergenerator}
*
* @author Benjamin Weißenfels
*
*/
public class LexTokDef extends ReadTokDefAbstract {
private HashMap<String, Boolean> seenPattern;
public LexTokDef(File regularDefinitionFile) throws IOException,
TokenDefinitionException {
super(regularDefinitionFile);
}
@Override
public void readFile(File file) throws TokenDefinitionException,
IOException {
BufferedReader br = new BufferedReader(new FileReader(file));
StringBuilder sb = new StringBuilder();
String pattern = null;
seenPattern = new HashMap<String, Boolean>();
definitions = new HashMap<String, String>();
rules = new ArrayList<IRule>();
int r = 0;
int col = 0;
line = 1;
// read declarations character wise
while ((r = br.read()) != -1) {
if ("%%".equals(sb.toString())) {
// delete the input
sb = new StringBuilder();
line++;
// read the rules
break;
}
col++;
if (r == '\t' && sb.length() > 0) {
pattern = sb.toString();
if (!seenPattern.containsKey(pattern)) {
seenPattern.put(pattern, true);
sb = new StringBuilder();
continue;
}
// this pattern was already, which makes no sense
throw new TokenDefinitionException(line, col,
"double pattern found");
}
// read the declaration identifier
if (r == '\n' && sb.length() > 0) {
String name = sb.toString().replace("{", "").replace("}", "");
if (pattern == null)
throw new TokenDefinitionException(line, col,
"no pattern defined");
// do not allow digits in declarations
if (name.matches("([0-9][0-9]*,[0-9][0-9]*)|([0-9][0-9]*)|([0-9][0-9]*,)")) {
throw new TokenDefinitionException(line, col,
"Number are not allowed in declarations");
}
// try to make a definition entry
if (!definitions.containsKey(name)) {
pattern = replaceDef(pattern);
definitions.put(name, pattern);
line++;
col = 0;
pattern = null;
sb = new StringBuilder();
continue;
}
// do not use a name for declaration twice
throw new TokenDefinitionException(line, col,
"this declaration name already exists");
}
// match some errors
if (r == '\n' && pattern != null) {
throw new TokenDefinitionException(line, col,
"missing declaration");
}
if (r == '\n') {
line++;
col = 0;
continue;
}
if (r == '\t') {
continue;
}
sb.append((char) r);
}
// read rules
while ((r = br.read()) != -1) {
col++;
if (r == '\t' && sb.length() > 0) {
pattern = sb.toString();
if (!seenPattern.containsKey(pattern)) {
pattern = replaceDef(pattern);
sb = new StringBuilder();
continue;
}
throw new TokenDefinitionException(line, "double pattern found");
}
if (r == '\n' && sb.length() > 0) {
if (pattern == null)
throw new TokenDefinitionException(line, col,
"no pattern defined");
// add the new rule
String action = sb.substring(1, sb.length() - 1);
IRule rule = new Rule(getTokenType(action),
getTokenValue(action), pattern);
rules.add(rule);
// set back some control variables
line++;
col = 0;
sb = new StringBuilder();
pattern = null;
continue;
}
// match some errors
if (r == '\n' && pattern != null) {
throw new TokenDefinitionException(line, col, "missing rule");
}
if (r == '\n') {
line++;
col = 0;
continue;
}
if (r == '\t') {
col++;
continue;
}
sb.append((char) r);
}
// read last line
if (r == -1 && sb.length() > 0) {
if (pattern == null)
throw new TokenDefinitionException(line, col,
"no pattern defined");
// add the new rule
String action = sb.substring(1, sb.length() - 1);
IRule rule = new Rule(getTokenType(action), getTokenValue(action),
pattern);
rules.add(rule);
// set back some control variables
line++;
col = 0;
}
}
}