Finished SynAn without good errors
This commit is contained in:
@@ -1,98 +1,205 @@
|
||||
package pins25.common;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Leksikalni simbol.
|
||||
*
|
||||
*
|
||||
* @param location Lokacija simbola v izvornem programu.
|
||||
* @param symbol Vrsta simbola.
|
||||
* @param lexeme Znakovna predstavitev simbola.
|
||||
*/
|
||||
public record Token(Report.Location location, Symbol symbol, String lexeme) implements Report.Locatable {
|
||||
|
||||
/**
|
||||
* Vrste leksikalnih simbolov.
|
||||
*/
|
||||
public enum Symbol {
|
||||
/** Konec datoteke. */
|
||||
EOF,
|
||||
/** Stevilo. */
|
||||
INTCONST,
|
||||
/** Znak. */
|
||||
CHARCONST,
|
||||
/** Niz znakov. */
|
||||
STRINGCONST,
|
||||
/** Ime. */
|
||||
IDENTIFIER,
|
||||
/** Kljucna beseda {@code fun}. */
|
||||
FUN,
|
||||
/** Kljucna beseda {@code var}. */
|
||||
VAR,
|
||||
/** Kljucna beseda {@code if}. */
|
||||
IF,
|
||||
/** Kljucna beseda {@code then}. */
|
||||
THEN,
|
||||
/** Kljucna beseda {@code else}. */
|
||||
ELSE,
|
||||
/** Kljucna beseda {@code while}. */
|
||||
WHILE,
|
||||
/** Kljucna beseda {@code do}. */
|
||||
DO,
|
||||
/** Kljucna beseda {@code let}. */
|
||||
LET,
|
||||
/** Kljucna beseda {@code in}. */
|
||||
IN,
|
||||
/** Kljucna beseda {@code end}. */
|
||||
END,
|
||||
/** Simbol {@code =}. */
|
||||
ASSIGN,
|
||||
/** Simbol {@code ,}. */
|
||||
COMMA,
|
||||
/** Simbol {@code &&}. */
|
||||
AND,
|
||||
/** Simbol {@code ||}. */
|
||||
OR,
|
||||
/** Simbol {@code !}. */
|
||||
NOT,
|
||||
/** Simbol {@code ==}. */
|
||||
EQU,
|
||||
/** Simbol {@code !=}. */
|
||||
NEQ,
|
||||
/** Simbol {@code >}. */
|
||||
GTH,
|
||||
/** Simbol {@code <}. */
|
||||
LTH,
|
||||
/** Simbol {@code >=}. */
|
||||
GEQ,
|
||||
/** Simbol {@code <=}. */
|
||||
LEQ,
|
||||
/** Simbol {@code +}. */
|
||||
ADD,
|
||||
/** Simbol {@code -}. */
|
||||
SUB,
|
||||
/** Simbol {@code *}. */
|
||||
MUL,
|
||||
/** Simbol {@code /}. */
|
||||
DIV,
|
||||
/** Simbol {@code %}. */
|
||||
MOD,
|
||||
/** Simbol {@code ^}. */
|
||||
PTR,
|
||||
/** Simbol {@code (}. */
|
||||
LPAREN,
|
||||
/** Simbol {@code )}. */
|
||||
RPAREN,
|
||||
}
|
||||
/**
|
||||
* Vrste leksikalnih simbolov.
|
||||
*/
|
||||
public enum Symbol {
|
||||
/**
|
||||
* Konec datoteke.
|
||||
*/
|
||||
EOF,
|
||||
/**
|
||||
* Stevilo.
|
||||
*/
|
||||
INTCONST,
|
||||
/**
|
||||
* Znak.
|
||||
*/
|
||||
CHARCONST,
|
||||
/**
|
||||
* Niz znakov.
|
||||
*/
|
||||
STRINGCONST,
|
||||
/**
|
||||
* Ime.
|
||||
*/
|
||||
IDENTIFIER,
|
||||
/**
|
||||
* Kljucna beseda {@code fun}.
|
||||
*/
|
||||
FUN,
|
||||
/**
|
||||
* Kljucna beseda {@code var}.
|
||||
*/
|
||||
VAR,
|
||||
/**
|
||||
* Kljucna beseda {@code if}.
|
||||
*/
|
||||
IF,
|
||||
/**
|
||||
* Kljucna beseda {@code then}.
|
||||
*/
|
||||
THEN,
|
||||
/**
|
||||
* Kljucna beseda {@code else}.
|
||||
*/
|
||||
ELSE,
|
||||
/**
|
||||
* Kljucna beseda {@code while}.
|
||||
*/
|
||||
WHILE,
|
||||
/**
|
||||
* Kljucna beseda {@code do}.
|
||||
*/
|
||||
DO,
|
||||
/**
|
||||
* Kljucna beseda {@code let}.
|
||||
*/
|
||||
LET,
|
||||
/**
|
||||
* Kljucna beseda {@code in}.
|
||||
*/
|
||||
IN,
|
||||
/**
|
||||
* Kljucna beseda {@code end}.
|
||||
*/
|
||||
END,
|
||||
/**
|
||||
* Simbol {@code =}.
|
||||
*/
|
||||
ASSIGN,
|
||||
/**
|
||||
* Simbol {@code ,}.
|
||||
*/
|
||||
COMMA,
|
||||
/**
|
||||
* Simbol {@code &&}.
|
||||
*/
|
||||
AND,
|
||||
/**
|
||||
* Simbol {@code ||}.
|
||||
*/
|
||||
OR,
|
||||
/**
|
||||
* Simbol {@code !}.
|
||||
*/
|
||||
NOT,
|
||||
/**
|
||||
* Simbol {@code ==}.
|
||||
*/
|
||||
EQU,
|
||||
/**
|
||||
* Simbol {@code !=}.
|
||||
*/
|
||||
NEQ,
|
||||
/**
|
||||
* Simbol {@code >}.
|
||||
*/
|
||||
GTH,
|
||||
/**
|
||||
* Simbol {@code <}.
|
||||
*/
|
||||
LTH,
|
||||
/**
|
||||
* Simbol {@code >=}.
|
||||
*/
|
||||
GEQ,
|
||||
/**
|
||||
* Simbol {@code <=}.
|
||||
*/
|
||||
LEQ,
|
||||
/**
|
||||
* Simbol {@code +}.
|
||||
*/
|
||||
ADD,
|
||||
/**
|
||||
* Simbol {@code -}.
|
||||
*/
|
||||
SUB,
|
||||
/**
|
||||
* Simbol {@code *}.
|
||||
*/
|
||||
MUL,
|
||||
/**
|
||||
* Simbol {@code /}.
|
||||
*/
|
||||
DIV,
|
||||
/**
|
||||
* Simbol {@code %}.
|
||||
*/
|
||||
MOD,
|
||||
/**
|
||||
* Simbol {@code ^}.
|
||||
*/
|
||||
PTR,
|
||||
/**
|
||||
* Simbol {@code (}.
|
||||
*/
|
||||
LPAREN,
|
||||
/**
|
||||
* Simbol {@code )}.
|
||||
*/
|
||||
RPAREN;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String lexeme = switch (symbol) {
|
||||
case INTCONST -> "(" + this.lexeme + ")";
|
||||
case CHARCONST -> "(" + this.lexeme + ")";
|
||||
case STRINGCONST -> "(" + this.lexeme + ")";
|
||||
case IDENTIFIER -> "(" + this.lexeme + ")";
|
||||
default -> "";
|
||||
};
|
||||
return location + " " + symbol + lexeme;
|
||||
}
|
||||
public String prettyPrint() {
|
||||
return switch (this) {
|
||||
case INTCONST -> "integer constant";
|
||||
case CHARCONST -> "character constant";
|
||||
case STRINGCONST -> "string constant";
|
||||
case IDENTIFIER -> "identifier";
|
||||
case FUN -> "'fun'";
|
||||
case VAR -> "'var'";
|
||||
case IF -> "'if'";
|
||||
case THEN -> "'then'";
|
||||
case ELSE -> "'else'";
|
||||
case WHILE -> "'while'";
|
||||
case DO -> "'do'";
|
||||
case LET -> "'let'";
|
||||
case IN -> "'in'";
|
||||
case END -> "'end'";
|
||||
case ASSIGN -> "'='";
|
||||
case COMMA -> "','";
|
||||
case AND -> "'&&'";
|
||||
case OR -> "'||'";
|
||||
case NOT -> "'!'";
|
||||
case EQU -> "'=='";
|
||||
case NEQ -> "'!='";
|
||||
case GTH -> "'>'";
|
||||
case LTH -> "'<'";
|
||||
case GEQ -> "'>='";
|
||||
case LEQ -> "'<='";
|
||||
case ADD -> "'+'";
|
||||
case SUB -> "'-'";
|
||||
case MUL -> "'*'";
|
||||
case DIV -> "'/'";
|
||||
case MOD -> "'%'";
|
||||
case PTR -> "'^'";
|
||||
case LPAREN -> "'('";
|
||||
case RPAREN -> "')'";
|
||||
default -> this.toString();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String lexeme = switch (symbol) {
|
||||
case INTCONST, IDENTIFIER, CHARCONST, STRINGCONST -> "(" + this.lexeme + ")";
|
||||
default -> "";
|
||||
};
|
||||
return location + " " + symbol + lexeme;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,7 +38,7 @@ public class SynAn implements AutoCloseable {
|
||||
private Token check(Token.Symbol symbol) {
|
||||
final Token token = lexAn.takeToken();
|
||||
if (token.symbol() != symbol)
|
||||
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected " + symbol + ".");
|
||||
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected " + symbol.prettyPrint() + ".");
|
||||
return token;
|
||||
}
|
||||
|
||||
@@ -54,21 +54,26 @@ public class SynAn implements AutoCloseable {
|
||||
}
|
||||
|
||||
private void parseProgram() {
|
||||
System.out.println("program -> definition restdefs");
|
||||
parseDefinition();
|
||||
parseRestDefinitions();
|
||||
}
|
||||
|
||||
private void parseRestDefinitions() {
|
||||
if (lexAn.peekToken().symbol() != Token.Symbol.EOF) {
|
||||
System.out.println("restdefs -> definition restdefs");
|
||||
parseDefinition();
|
||||
parseRestDefinitions();
|
||||
} else {
|
||||
System.out.println("restdefs -> ε");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDefinition() {
|
||||
Token token = lexAn.peekToken();
|
||||
switch (token.symbol()) {
|
||||
case Token.Symbol.FUN:
|
||||
case FUN:
|
||||
System.out.println("definition -> FUN IDENTIFIER LPAREN parameters RPAREN funcassign");
|
||||
check(Token.Symbol.FUN);
|
||||
check(Token.Symbol.IDENTIFIER);
|
||||
check(Token.Symbol.LPAREN);
|
||||
@@ -77,7 +82,8 @@ public class SynAn implements AutoCloseable {
|
||||
parseFunctionAssignment();
|
||||
break;
|
||||
|
||||
case Token.Symbol.VAR:
|
||||
case VAR:
|
||||
System.out.println("definition -> VAR IDENTIFIER ASSIGN initializers");
|
||||
check(Token.Symbol.VAR);
|
||||
check(Token.Symbol.IDENTIFIER);
|
||||
check(Token.Symbol.ASSIGN);
|
||||
@@ -91,78 +97,80 @@ public class SynAn implements AutoCloseable {
|
||||
|
||||
private void parseFunctionAssignment() {
|
||||
Token token = lexAn.peekToken();
|
||||
switch (token.symbol()) {
|
||||
case Token.Symbol.FUN:
|
||||
case Token.Symbol.VAR:
|
||||
case Token.Symbol.IN:
|
||||
case Token.Symbol.EOF:
|
||||
break;
|
||||
|
||||
case Token.Symbol.ASSIGN:
|
||||
check(Token.Symbol.ASSIGN);
|
||||
parseStatements();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected ASSIGN.");
|
||||
if (token.symbol() == Token.Symbol.ASSIGN) {
|
||||
System.out.println("funcassign -> ASSIGN statements");
|
||||
check(Token.Symbol.ASSIGN);
|
||||
parseStatements();
|
||||
} else {
|
||||
System.out.println("funcassign -> ε");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseParameters() {
|
||||
Token token = lexAn.peekToken();
|
||||
switch (token.symbol()) {
|
||||
case Token.Symbol.IDENTIFIER:
|
||||
check(Token.Symbol.IDENTIFIER);
|
||||
parseRestParameters();
|
||||
break;
|
||||
|
||||
case Token.Symbol.RPAREN:
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected IDENTIFIER or RPAREN.");
|
||||
if (token.symbol() == Token.Symbol.IDENTIFIER) {
|
||||
System.out.println("parameters -> IDENTIFIER restparams");
|
||||
check(Token.Symbol.IDENTIFIER);
|
||||
parseRestParameters();
|
||||
} else {
|
||||
System.out.println("parameters -> ε");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseRestParameters() {
|
||||
Token token = lexAn.peekToken();
|
||||
switch (token.symbol()) {
|
||||
case Token.Symbol.RPAREN:
|
||||
break;
|
||||
|
||||
case Token.Symbol.COMMA:
|
||||
check(Token.Symbol.COMMA);
|
||||
check(Token.Symbol.IDENTIFIER);
|
||||
parseRestParameters();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected ')' or ','.");
|
||||
if (token.symbol() == Token.Symbol.COMMA) {
|
||||
System.out.println("restparams -> COMMA IDENTIFIER restparams");
|
||||
check(Token.Symbol.COMMA);
|
||||
check(Token.Symbol.IDENTIFIER);
|
||||
parseRestParameters();
|
||||
} else {
|
||||
System.out.println("restparams -> ε");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseStatements() {
|
||||
System.out.println("statements -> statement reststmts");
|
||||
parseStatement();
|
||||
parseRestStatements();
|
||||
}
|
||||
|
||||
private void parseExpressionAssign() {
|
||||
if (lexAn.peekToken().symbol() == Token.Symbol.ASSIGN) {
|
||||
System.out.println("exprassign -> ASSIGN expression");
|
||||
check(Token.Symbol.ASSIGN);
|
||||
parseExpression();
|
||||
} else {
|
||||
System.out.println("exprassign -> ε");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseElseStatement() {
|
||||
if (lexAn.peekToken().symbol() == Token.Symbol.ELSE) {
|
||||
System.out.println("elsestmt -> ELSE statements");
|
||||
check(Token.Symbol.ELSE);
|
||||
parseStatements();
|
||||
} else {
|
||||
System.out.println("elsestmt -> ε");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseRestStatements() {
|
||||
if (lexAn.peekToken().symbol() == Token.Symbol.COMMA) {
|
||||
System.out.println("reststmts -> COMMA statement reststmts");
|
||||
check(Token.Symbol.COMMA);
|
||||
parseStatement();
|
||||
parseRestStatements();
|
||||
} else {
|
||||
System.out.println("reststmts -> ε");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseStatement() {
|
||||
Token token = lexAn.peekToken();
|
||||
switch (token.symbol()) {
|
||||
case Token.Symbol.IDENTIFIER:
|
||||
case Token.Symbol.LPAREN:
|
||||
case Token.Symbol.ADD:
|
||||
case Token.Symbol.SUB:
|
||||
case Token.Symbol.NOT:
|
||||
case Token.Symbol.PTR:
|
||||
case Token.Symbol.INTCONST:
|
||||
case Token.Symbol.CHARCONST:
|
||||
case Token.Symbol.STRINGCONST:
|
||||
parseExpression();
|
||||
parseExpressionAssign();
|
||||
break;
|
||||
|
||||
case Token.Symbol.IF:
|
||||
case IF:
|
||||
System.out.println("statement -> if expression then statements elsestmt end");
|
||||
check(Token.Symbol.IF);
|
||||
parseExpression();
|
||||
check(Token.Symbol.THEN);
|
||||
@@ -171,7 +179,8 @@ public class SynAn implements AutoCloseable {
|
||||
check(Token.Symbol.END);
|
||||
break;
|
||||
|
||||
case Token.Symbol.WHILE:
|
||||
case WHILE:
|
||||
System.out.println("statement -> while expression do statements end");
|
||||
check(Token.Symbol.WHILE);
|
||||
parseExpression();
|
||||
check(Token.Symbol.DO);
|
||||
@@ -179,7 +188,8 @@ public class SynAn implements AutoCloseable {
|
||||
check(Token.Symbol.END);
|
||||
break;
|
||||
|
||||
case Token.Symbol.LET:
|
||||
case LET:
|
||||
System.out.println("statement -> let definition reststmtdefs in statements end");
|
||||
check(Token.Symbol.LET);
|
||||
parseDefinition();
|
||||
parseRestStatementDefinitions();
|
||||
@@ -187,33 +197,318 @@ public class SynAn implements AutoCloseable {
|
||||
parseStatements();
|
||||
check(Token.Symbol.END);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void parseRestStatements() {
|
||||
if (lexAn.peekToken().symbol() == Token.Symbol.COMMA) {
|
||||
check(Token.Symbol.COMMA);
|
||||
parseStatements();
|
||||
default:
|
||||
System.out.println("statement -> expression exprassign");
|
||||
parseExpression();
|
||||
parseExpressionAssign();
|
||||
}
|
||||
}
|
||||
|
||||
private void parseRestStatementDefinitions() {
|
||||
switch (lexAn.peekToken().symbol()) {
|
||||
case IN:
|
||||
System.out.println("reststmtdefs -> ε");
|
||||
break;
|
||||
|
||||
case FUN:
|
||||
case VAR:
|
||||
System.out.println("reststmtdefs -> definition reststmtdefs");
|
||||
parseDefinition();
|
||||
parseRestStatementDefinitions();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void parseInitializers() {
|
||||
switch (lexAn.peekToken().symbol()) {
|
||||
case INTCONST:
|
||||
case CHARCONST:
|
||||
case STRINGCONST:
|
||||
System.out.println("initializers -> initializer restinits");
|
||||
parseInitializer();
|
||||
parseRestInitializers();
|
||||
break;
|
||||
|
||||
default:
|
||||
System.out.println("initializers -> ε");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void parseInitializer() {
|
||||
Token token = lexAn.peekToken();
|
||||
switch (token.symbol()) {
|
||||
case INTCONST:
|
||||
System.out.println("initializer -> INTCONST intconstmult");
|
||||
check(Token.Symbol.INTCONST);
|
||||
parseIntegerConstantMultiplier();
|
||||
break;
|
||||
|
||||
case CHARCONST:
|
||||
System.out.println("initializer -> CHARCONST");
|
||||
check(Token.Symbol.CHARCONST);
|
||||
break;
|
||||
|
||||
case STRINGCONST:
|
||||
System.out.println("initializer -> STRINGCONST");
|
||||
check(Token.Symbol.STRINGCONST);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected integer, character or string constant.");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseRestInitializers() {
|
||||
Token token = lexAn.peekToken();
|
||||
if (token.symbol() == Token.Symbol.COMMA) {
|
||||
System.out.println("restinits -> COMMA initializer restinits");
|
||||
check(Token.Symbol.COMMA);
|
||||
parseInitializer();
|
||||
parseRestInitializers();
|
||||
} else {
|
||||
System.out.println("restinits -> ε");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseIntegerConstantMultiplier() {
|
||||
Token token = lexAn.peekToken();
|
||||
if (token.symbol() == Token.Symbol.MUL) {
|
||||
System.out.println("intconstmult -> MUL const");
|
||||
check(Token.Symbol.MUL);
|
||||
parseConstant();
|
||||
} else {
|
||||
System.out.println("intconstmult -> ε");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseConstant() {
|
||||
Token token = lexAn.peekToken();
|
||||
switch (token.symbol()) {
|
||||
case INTCONST:
|
||||
System.out.println("const -> INTCONST");
|
||||
check(Token.Symbol.INTCONST);
|
||||
break;
|
||||
|
||||
case CHARCONST:
|
||||
System.out.println("const -> CHARCONST");
|
||||
check(Token.Symbol.CHARCONST);
|
||||
break;
|
||||
|
||||
case STRINGCONST:
|
||||
System.out.println("const -> STRINGCONST");
|
||||
check(Token.Symbol.STRINGCONST);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected integer, character or string constant.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void parseExpression() {
|
||||
System.out.println("expression -> conjexpr restdisj");
|
||||
parseConjunctionExpression();
|
||||
parseRestDisjunctions();
|
||||
}
|
||||
|
||||
private void parseExpressionAssign() {
|
||||
private void parseRestDisjunctions() {
|
||||
if (lexAn.peekToken().symbol() == Token.Symbol.OR) {
|
||||
System.out.println("restdisj -> OR conjexpr restdisj");
|
||||
check(Token.Symbol.OR);
|
||||
parseConjunctionExpression();
|
||||
parseRestDisjunctions();
|
||||
}
|
||||
}
|
||||
|
||||
private void parseElseStatement() {
|
||||
private void parseConjunctionExpression() {
|
||||
System.out.println("conjexpr -> cmpexpr restconj");
|
||||
parseComparisonExpression();
|
||||
parseRestConjunctionExpressions();
|
||||
}
|
||||
|
||||
private void parseRestConjunctionExpressions() {
|
||||
if (lexAn.peekToken().symbol() == Token.Symbol.AND) {
|
||||
System.out.println("restconj -> AND cmpexpr restconj");
|
||||
check(Token.Symbol.AND);
|
||||
parseComparisonExpression();
|
||||
parseRestConjunctionExpressions();
|
||||
} else {
|
||||
System.out.println("restconj -> ε");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseComparisonExpression() {
|
||||
System.out.println("cmpexpr -> addexpr restcmp");
|
||||
parseAdditionExpression();
|
||||
parseRestComparisons();
|
||||
}
|
||||
|
||||
private void parseRestComparisons() {
|
||||
Token token = lexAn.peekToken();
|
||||
switch (token.symbol()) {
|
||||
case EQU:
|
||||
case NEQ:
|
||||
case LTH:
|
||||
case GTH:
|
||||
case LEQ:
|
||||
case GEQ:
|
||||
System.out.printf("restcmp -> %s addexpr\n", token.symbol());
|
||||
check(token.symbol());
|
||||
parseAdditionExpression();
|
||||
break;
|
||||
|
||||
default:
|
||||
System.out.println("restcmp -> ε");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void parseAdditionExpression() {
|
||||
System.out.println("addexpr -> multexpr restadd");
|
||||
parseMultiplicationExpression();
|
||||
parseRestAdditions();
|
||||
}
|
||||
|
||||
private void parseRestAdditions() {
|
||||
Token token = lexAn.peekToken();
|
||||
switch (token.symbol()) {
|
||||
case ADD:
|
||||
case SUB:
|
||||
System.out.printf("restadd -> %s multexpr restadd\n", token.symbol());
|
||||
check(token.symbol());
|
||||
parseMultiplicationExpression();
|
||||
parseRestAdditions();
|
||||
break;
|
||||
|
||||
default:
|
||||
System.out.println("restadd -> ε");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void parseMultiplicationExpression() {
|
||||
System.out.println("multexpr -> prefixexpr restmult");
|
||||
parsePrefixExpression();
|
||||
parseRestMultiplicationExpressions();
|
||||
}
|
||||
|
||||
private void parseRestMultiplicationExpressions() {
|
||||
Token token = lexAn.peekToken();
|
||||
switch (token.symbol()) {
|
||||
case MUL:
|
||||
case DIV:
|
||||
case MOD:
|
||||
System.out.printf("restmult -> %s prefixexpr restmult\n", token.symbol());
|
||||
check(token.symbol());
|
||||
parsePrefixExpression();
|
||||
parseRestMultiplicationExpressions();
|
||||
break;
|
||||
|
||||
default:
|
||||
System.out.println("restmult -> ε");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void parsePrefixExpression() {
|
||||
Token token = lexAn.peekToken();
|
||||
switch (token.symbol()) {
|
||||
case ADD:
|
||||
case SUB:
|
||||
case NOT:
|
||||
case PTR:
|
||||
System.out.printf("prefixexpr -> %s prefixexpr\n", token.symbol());
|
||||
check(token.symbol());
|
||||
parsePrefixExpression();
|
||||
break;
|
||||
|
||||
default:
|
||||
System.out.println("prefixexpr -> postfixexpr");
|
||||
parsePostfixExpression();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void parsePostfixExpression() {
|
||||
System.out.println("postfixexpr -> primary postfixop");
|
||||
parsePrimary();
|
||||
parsePostfixOperator();
|
||||
}
|
||||
|
||||
private void parsePostfixOperator() {
|
||||
if (lexAn.peekToken().symbol() == Token.Symbol.PTR) {
|
||||
System.out.println("postfixop -> PTR postfixop");
|
||||
check(Token.Symbol.PTR);
|
||||
parsePostfixOperator();
|
||||
} else {
|
||||
System.out.println("postfixop -> ε");
|
||||
}
|
||||
}
|
||||
|
||||
private void parsePrimary() {
|
||||
Token token = lexAn.peekToken();
|
||||
switch (token.symbol()) {
|
||||
case IDENTIFIER:
|
||||
System.out.println("primary -> IDENTIFIER exprargs");
|
||||
check(Token.Symbol.IDENTIFIER);
|
||||
parseExpressionArguments();
|
||||
break;
|
||||
|
||||
case LPAREN:
|
||||
System.out.println("primary -> LPAREN expression RPAREN");
|
||||
check(Token.Symbol.LPAREN);
|
||||
parseExpression();
|
||||
check(Token.Symbol.RPAREN);
|
||||
break;
|
||||
|
||||
case INTCONST:
|
||||
case CHARCONST:
|
||||
case STRINGCONST:
|
||||
System.out.println("primary -> const");
|
||||
parseConstant();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected identifier, constant or '('.");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseExpressionArguments() {
|
||||
if (lexAn.peekToken().symbol() == Token.Symbol.LPAREN) {
|
||||
System.out.println("exprargs -> LPAREN arguments RPAREN");
|
||||
check(Token.Symbol.LPAREN);
|
||||
parseArguments();
|
||||
check(Token.Symbol.RPAREN);
|
||||
} else {
|
||||
System.out.println("exprargs -> ε");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseArguments() {
|
||||
Token token = lexAn.peekToken();
|
||||
if (token.symbol() == Token.Symbol.RPAREN) {
|
||||
System.out.println("arguments -> ε");
|
||||
} else {
|
||||
System.out.println("arguments -> expression restargs");
|
||||
parseExpression();
|
||||
parseRestArguments();
|
||||
}
|
||||
}
|
||||
|
||||
private void parseRestArguments() {
|
||||
if (lexAn.peekToken().symbol() == Token.Symbol.COMMA) {
|
||||
System.out.println("restargs -> COMMA restargs");
|
||||
check(Token.Symbol.COMMA);
|
||||
parseExpression();
|
||||
parseRestArguments();
|
||||
} else {
|
||||
System.out.println("restargs -> ε");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --- ZAGON ---
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user