Полный код проекта в C2j-компилятором
предисловие
Предыдущая информация официально завершила строительство и достаточное решение уменьшить конечный автомат, следующая задача состоит в том, чтобы заполнить таблицу синтаксического анализа на основе конечного автомата и синтаксического анализа осуществляется в соответствии с таблицей
уменьшить информацию
До завершения синтаксического анализа таблицы, есть еще последняя задача, которая описывает уменьшить информацию автоматически направлять машину, если выполняется снизить эксплуатационные
ProductionsStateNode уменьшить информацию в каждом узле завершена, в обход узла в производстве, если знак «» в конце выражения, то узел может быть получена на основе информации, выражения и уменьшить набор LookAhead, соответствующее выражению
уменьшить информацию, чтобы указать карту, ключевые символы могут быть выполнены, чтобы уменьшить, то есть в соответствии с наборами упреждающего, значение операции производства снижают
public HashMap<Integer, Integer> makeReduce() {
HashMap<Integer, Integer> map = new HashMap<>();
reduce(map, this.productions);
reduce(map, this.mergedProduction);
return map;
}
private void reduce(HashMap<Integer, Integer> map, ArrayList<Production> productions) {
for (int i = 0; i < productions.size(); i++) {
if (productions.get(i).canBeReduce()) {
ArrayList<Integer> lookAhead = productions.get(i).getLookAheadSet();
for (int j = 0; j < lookAhead.size(); j++) {
map.put(lookAhead.get(j), (productions.get(i).getProductionNum()));
}
}
}
}
Построение таблицы синтаксического анализа
Построение таблиц разбора, главным образом, в классе StateNodeManager, вы можете игнорировать логику loadTable и storageTableToFile этой части в основном хранить эту таблицу, можно использовать несколько раз
От основная логика начинается во время прохождения всех узлов, начинает прыгать информацию Карты по отношению к прыгать и прыгать узел назначения, то соответствующий (скачок от характера отношений является позицией начала маркеров перечисления ссылка) и копируется на другой узел назначения в карте. В соответствующей упреждающей выборке, поставленной перед затем уменьшить, чтобы получить информацию, символ найден, то его значение переписывается - (для операции производства уменьшить количество), причину отрицательного письменную, чтобы отличить операцию сдвига.
Поэтому HashMap <Целое число, HashMap <Целое, Целое >> эта структура данных представляет собой таблицу в качестве анализа:
- Первое число представляет текущий узел Integer
- Второе Целое число представляет входной символ
- Целое треть, больше 0, если операция сдвига сделана меньше 0 вы уменьшить операцию согласно деривации
public HashMap<Integer, HashMap<Integer, Integer>> getLrStateTable() {
File table = new File("lrStateTable.sb");
if (table.exists()) {
return loadTable();
}
Iterator it;
if (isTransitionTableCompressed) {
it = compressedStateList.iterator();
} else {
it = stateList.iterator();
}
while (it.hasNext()) {
ProductionsStateNode state = (ProductionsStateNode) it.next();
HashMap<Integer, ProductionsStateNode> map = transitionMap.get(state);
HashMap<Integer, Integer> jump = new HashMap<>();
if (map != null) {
for (Map.Entry<Integer, ProductionsStateNode> item : map.entrySet()) {
jump.put(item.getKey(), item.getValue().stateNum);
}
}
HashMap<Integer, Integer> reduceMap = state.makeReduce();
if (reduceMap.size() > 0) {
for (Map.Entry<Integer, Integer> item : reduceMap.entrySet()) {
jump.put(item.getKey(), -(item.getValue()));
}
}
lrStateTable.put(state.stateNum, jump);
}
storageTableToFile(lrStateTable);
return lrStateTable;
}
Табличной разборе
Основной процесс разбора класса LRStateTableParser, инициированный с помощью метода синтаксического анализа.
Второй и выступая в качестве необходимого стека ввода, узла стека, другой вещи, теперь нет необходимости использовать. При инициализации первого запуска узла в стек, текущих входном наборе символов EXT_DEF_LIST, а затем получить таблицу синтаксического анализа
public LRStateTableParser(Lexer lexer) {
this.lexer = lexer;
statusStack.push(0);
valueStack.push(null);
lexer.advance();
lexerInput = Token.EXT_DEF_LIST.ordinal();
lrStateTable = StateNodeManager.getInstance().getLrStateTable();
}
Синтаксические этапов:
- Получить текущий символ в текущем узле и соответствующую операцию, т.е. действие> 0 является операция сдвига, действие <0 снизить операцию
- Если ввести действие> 0, то есть операции сдвига
- Текущее состояние узла и ввод символов в стеке
- Здесь мы должны различать, если текущий символ является терминатором, на этот раз мы можем сразу прочитать следующий символ
- Однако, если есть не-терминальный символ, текущий символ должен быть использован, чтобы перейти непосредственно к следующему состоянию. Одно предостережение здесь является точкой, где текущие потребности нетерминала, помещаются рядом с соответствующим входным узлом в стеке, так, чтобы уменьшить, когда операция стеки поп-обратно символ является правильной
- Если действие> 0, то есть, уменьшить эксплуатационные
- Для того, чтобы получить соответствующее производство
- Производство состояние узел, соответствующий правой части стека поп
- Полный уменьшить этот символ в стеке ввода
public void parse() {
while (true) {
Integer action = getAction(statusStack.peek(), lexerInput);
if (action == null) {
ConsoleDebugColor.outlnPurple("Shift for input: " + Token.values()[lexerInput].toString());
System.err.println("The input is denied");
return;
}
if (action > 0) {
statusStack.push(action);
text = lexer.text;
// if (lexerInput == Token.RELOP.ordinal()) {
// relOperatorText = text;
// }
parseStack.push(lexerInput);
if (Token.isTerminal(lexerInput)) {
ConsoleDebugColor.outlnPurple("Shift for input: " + Token.values()[lexerInput].toString() + " text: " + text);
// Object obj = takeActionForShift(lexerInput);
lexer.advance();
lexerInput = lexer.lookAhead;
// valueStack.push(obj);
} else {
lexerInput = lexer.lookAhead;
}
} else {
if (action == 0) {
ConsoleDebugColor.outlnPurple("The input can be accepted");
return;
}
int reduceProduction = -action;
Production product = ProductionManager.getInstance().getProductionByIndex(reduceProduction);
ConsoleDebugColor.outlnPurple("reduce by product: ");
product.debugPrint();
// takeActionForReduce(reduceProduction);
int rightSize = product.getRight().size();
while (rightSize > 0) {
parseStack.pop();
// valueStack.pop();
statusStack.pop();
rightSize--;
}
lexerInput = product.getLeft();
parseStack.push(lexerInput);
// valueStack.push(attributeForParentNode);
}
}
}
private Integer getAction(Integer currentState, Integer currentInput) {
HashMap<Integer, Integer> jump = lrStateTable.get(currentState);
return jump.get(currentInput);
}
Неоднозначность грамматики
А теперь завершила все синтаксический анализ контента, семантический анализ следует, но до того, что есть необходимость сказать, что наша текущая конструкция конечный автомат относится к (1) грамматики LALR, даже LALR (1) синтаксис достаточно сильный, но все же существуют LALR (1) грамматика не может справиться с синтаксисом, если данный вывод не соответствует, то конечный автомат еще не правильно решены, но синтаксис данного ранее в соответствии с LALR (1 ) синтаксис
резюме
Это является одним из основных
- Конечный автомат и уменьшить информационную таблицу завершается разбор
- Реализация таблицы с использованием синтаксиса синтаксического анализ таблицы управляемого разбора