Я пытаюсь разработать простой язык, похожий на губы, схему. Я написал свой лексер (токенизатор). Я могу разделить на операторы, идентификаторы и т. д. Но я сейчас пытаюсь написать парсер. Для этого мне достаточно одного примера. Может кто-нибудь привести пример в java-коде просто для примера? Кроме того, все упоминают об использовании antlr. Может ли кто-нибудь, кто пытается использовать antlr, показать пример, используя мой пример в этом вопросе?
- –
EXP -> EXPI | EXPB
- –
EXPI -> (+ EXPI EXPI) | (- EXPI EXPI) | (* EXPI EXPI) | (/ EXPI EXPI) | Id | IntegerValue | (Id EXPLIST)
- –
EXPB -> (and EXPB EXPB)
если мой ввод (+ 1 2)
, я надеюсь получить в качестве вывода
- START-> INPUT
- -> EXP
- -> EXPI
- -> (+ EXPI EXPI)
- -> (+ EXPI Id)
- -> (+ Id Id)
Речь идет о LR (разбор сдвига-уменьшения). У меня есть простой пример, и я не знаю, могу ли я изменить код для синтаксического анализа. Но, что привлекает мое внимание, использование стека подходит для алгоритма LR. Не так ли?
import java.util.Stack;
public class SmallLisp {
Stack<String> stack;
public SmallLisp(){
String[] tokens = new String[]{"(","+","2","(","+","3","2",")",")",};
stack = new Stack<String>();
for (int i=0;i<tokens.length;i++){
stack.push(tokens[i]);
if(tokens[i].equals(")")) Interprete();
}
}
public void Interprete(){
String tok;
Stack<String> callStack = new Stack<String>();
tok = stack.pop(); /* This is the ) character */
while(!(tok=stack.pop()).equals("(")){
callStack.push(tok);
}
Call(callStack);
}
public void Call(Stack<String> callStack){
String func = callStack.pop(); /* This is the operator or function */
if(func.equals("+")) {
double result = Plus(callStack);
stack.push(String.valueOf(result));
}
//if(func.equals("-")) Minus(callStack);
}
public double Plus(Stack<String> callStack){
double a = Double.parseDouble(callStack.pop());
double b = Double.parseDouble(callStack.pop());
System.out.println("Answer is "+(a+b));
return(a+b);
}
public static void main(String[] args) {
new SmallLisp();
}
}
switch
вместо таблицы перехода (массива). Но вам все равно нужно знать все состояния парсера и способы перехода между ними (подсказка: вершина стека — это текущее состояние парсера, которое выswitch
используете.) - person scooter me fecit   schedule 23.12.2015exp ::= id | number | (exp exp exp)
. Затем, когда вы оцениваете выражения (после того, как вы их проанализировали), вы можете жаловаться на семантические ошибки, такие как число в позиции функции. - person Joshua Taylor   schedule 23.12.2015(oper exp exp)
с правиломoper
oper -> '+' | '-' | '*' | '/'
? - person scooter me fecit   schedule 23.12.2015((lambda (x) ...) ...)
; вам понадобятся выражения, чтобы иметь возможность отображаться в качестве первого элемента списка. Как я уже сказал, это, вероятно, будет проще реализовать в интерпретаторе/оценщике. Там проще определить модель оценки как ту, которая проверяет, является ли первый элемент +, -, * или /, и выдает ошибку, если это не так. Вопрос, как написано, касается синтаксического анализа Scheme/Lisp, а парсер Scheme/Lisp разрешает другие вещи в первой позиции. - person Joshua Taylor   schedule 23.12.2015