Finished SynAn without good errors

This commit is contained in:
Gašper Dobrovoljc 2025-03-21 15:28:24 +01:00
parent b1e61398a6
commit a94802b571
No known key found for this signature in database
GPG Key ID: 0E7E037018CFA5A5
9 changed files with 688 additions and 173 deletions

View File

@ -1,6 +1,8 @@
<component name="InspectionProjectProfileManager"> <component name="InspectionProjectProfileManager">
<profile version="1.0"> <profile version="1.0">
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<inspection_tool class="GrazieInspection" enabled="false" level="GRAMMAR_ERROR" enabled_by_default="false" />
<inspection_tool class="LanguageDetectionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredIdentifiers"> <option name="ignoredIdentifiers">
<list> <list>
@ -8,5 +10,10 @@
</list> </list>
</option> </option>
</inspection_tool> </inspection_tool>
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />
</inspection_tool>
</profile> </profile>
</component> </component>

8
.idea/misc.xml generated
View File

@ -1,4 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.12" />
</component>
<component name="PWA">
<option name="enabled" value="true" />
<option name="wasEnabledAtLeastOnce" value="true" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_23" default="true" project-jdk-name="homebrew-23" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_23" default="true" project-jdk-name="homebrew-23" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>

53
generate.py Normal file
View File

@ -0,0 +1,53 @@
from collections import defaultdict
data = open('./grammar.txt').read().split()
productions = defaultdict(lambda: [])
def recurse(prod):
prods = []
if prod not in productions.keys():
prods.append(prod)
else:
for p in productions[prod]:
if len(p):
prods += recurse(p[0])
return prods
while len(data):
name = data.pop(0)
data.pop(0) # ->
symbols = []
while True:
symbol = data.pop(0)
if symbol == '.':
productions[name].append(symbols)
break
if symbol == '|':
productions[name].append(symbols)
symbols = []
continue
symbols.append(symbol)
for prod, defs in productions.items():
func = f"""private void {prod}() {{
Token token = lexAn.peekToken();
switch(token.symbol()) {{
"""
for d in defs:
for r in recurse(d[0]):
func += f" case {r}:\n"
func += f' System.out.println("{prod} -> {defs}");'
for d2 in d:
if d2.isupper():
func += f"check({d2});"
func += """ }
}"""
print(func)

View File

@ -1,48 +1,54 @@
program -> definition restdefs . program -> definition restdefs .
restdefs -> definition restdefs | . restdefs -> definition restdefs | .
definition -> fun IDENTIFIER LPAREN parameters RPAREN funcassign . definition -> FUN IDENTIFIER LPAREN parameters RPAREN funcassign .
funcassign -> ASSIGN statements | . funcassign -> ASSIGN statements | .
definition -> var IDENTIFIER ASSING initializers . definition -> VAR IDENTIFIER ASSIGN initializers .
parameters -> IDENTIFIER restparams | . parameters -> IDENTIFIER restparams | .
restparams -> COMMA parameters | . restparams -> COMMA IDENTIFIER restparams | .
statements -> statement reststmts . statements -> statement reststmts .
reststmts -> COMMA statements | . reststmts -> COMMA statement reststmts | .
statement -> expression exprassign . statement -> expression exprassign .
exprassign -> ASSIGN expression | . exprassign -> ASSIGN expression | .
statement -> if expression then statements elsestmt end . statement -> IF expression THEN statements elsestmt END .
elsestmt -> else statements | . elsestmt -> ELSE statements | .
statement -> while expression do statements end . statement -> WHILE expression DO statements END .
statement -> let definition reststmtdefs in statements end . statement -> LET definition reststmtdefs IN statements END .
reststmtdefs -> definition reststmtdefs | . reststmtdefs -> definition reststmtdefs | .
expression -> conjexpr restdisj . expression -> conjexpr restdisj .
restdisj -> OR expression | . restdisj -> OR conjexpr restdisj | .
conjexpr -> cmpexpr restconj . conjexpr -> cmpexpr restconj .
restconj -> AND conjexpr | . restconj -> AND cmpexpr restconj | .
cmpexpr -> addexpr restcmp . cmpexpr -> addexpr restcmp .
restcmp -> cmpop cmpexpr | . restcmp -> EQU addexpr
cmpop -> EQ | NEQ | LTH | GTH | LEQ | GEQ . | NEQ addexpr
| LTH addexpr
| GTH addexpr
| LEQ addexpr
| GEQ addexpr
| .
addexpr -> multexpr restadd . addexpr -> multexpr restadd .
restadd -> addop addexpr | . restadd -> ADD multexpr restadd
addop -> ADD | SUB . | SUB multexpr restadd | .
multexpr -> prefixexpr restmult . multexpr -> prefixexpr restmult .
restmult -> multop multexpr | . restmult -> MUL prefixexpr restmult
multop -> MUL | DIV | MOD . | DIV prefixexpr restmult
| MOD prefixexpr restmult
| .
prefixexpr -> prefixop postfixexpr . prefixexpr -> NOT prefixexpr | ADD prefixexpr | SUB prefixexpr | PTR prefixexpr | postfixexpr .
prefixop -> NOT prefixop | ADD prefixop | SUB prefixop | PTR prefixop | .
postfixexpr -> primary postfixop . postfixexpr -> primary postfixop .
postfixop -> PTR postfixop | . postfixop -> PTR postfixop | .
@ -51,12 +57,12 @@ primary -> const | LPAREN expression RPAREN | IDENTIFIER exprargs .
exprargs -> LPAREN arguments RPAREN | . exprargs -> LPAREN arguments RPAREN | .
arguments -> expression restargs | . arguments -> expression restargs | .
restargs -> COMMA restargs | . restargs -> COMMA expression restargs | .
initializers -> initializer restinits | . initializers -> initializer restinits | .
restinits -> COMMA initializers | . restinits -> COMMA initializer restinits | .
initializer -> INTCONST intconstmul | CHARCONST | STRINGCONST . initializer -> INTCONST intconstmult | CHARCONST | STRINGCONST .
intconstmul -> MUL const | . intconstmult -> MUL const | .
const -> INTCONST | CHARCONST | STRINGCONST . const -> INTCONST | CHARCONST | STRINGCONST .

View File

@ -1,5 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4"> <module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Python" name="Python">
<configuration sdkName="Python 3.12" />
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true"> <component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
@ -7,5 +12,6 @@
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Python 3.12 interpreter library" level="application" />
</component> </component>
</module> </module>

35
prg/pass.pins Normal file
View File

@ -0,0 +1,35 @@
fun noarg()
fun onearg(a)
fun multargs(a, b)
fun funcassign(a) =
a = 1
var a = 1
var b = 'a'
var c = "test"
var e = 'a', "test", 4
var f = 1 * 3
var g = 1 * 'a'
var h = 4 * "aaa"
fun a() =
1, 'a', "a",
a, neki(a, 1, 'a', "a"),
a^, a^^,
+a, -a, !a, ^a, +-!^a,
a * b, a / b, a % b, a * b / c % d,
a + b, a - b,
a == b, a != b, a < b, a > b, a <= b, a >= b,
a && b, a && b && c,
a || b, a || b || c,
(1), (a + b), (a - (!(1) * 2)),
a + 1 = b - 1,
if a then b end,
if a == 3 then b = 1, !c end,
if !a then b else a = 3 * a end,
if a then b else a, b end,
while a <= 10 do a + 1 end,
while a <= 10 do a + 1, ^c end,
let fun a(b, c) in !b end,
let fun a(b, c) var e = 'o' in !b end,
let fun a(b, c) in !b, 4 end

View File

@ -1,2 +0,0 @@
fun test(a, b,,) =
var c = 0

View File

@ -1,5 +1,7 @@
package pins25.common; package pins25.common;
import java.util.HashMap;
/** /**
* Leksikalni simbol. * Leksikalni simbol.
* *
@ -13,83 +15,188 @@ public record Token(Report.Location location, Symbol symbol, String lexeme) impl
* Vrste leksikalnih simbolov. * Vrste leksikalnih simbolov.
*/ */
public enum Symbol { public enum Symbol {
/** Konec datoteke. */ /**
* Konec datoteke.
*/
EOF, EOF,
/** Stevilo. */ /**
* Stevilo.
*/
INTCONST, INTCONST,
/** Znak. */ /**
* Znak.
*/
CHARCONST, CHARCONST,
/** Niz znakov. */ /**
* Niz znakov.
*/
STRINGCONST, STRINGCONST,
/** Ime. */ /**
* Ime.
*/
IDENTIFIER, IDENTIFIER,
/** Kljucna beseda {@code fun}. */ /**
* Kljucna beseda {@code fun}.
*/
FUN, FUN,
/** Kljucna beseda {@code var}. */ /**
* Kljucna beseda {@code var}.
*/
VAR, VAR,
/** Kljucna beseda {@code if}. */ /**
* Kljucna beseda {@code if}.
*/
IF, IF,
/** Kljucna beseda {@code then}. */ /**
* Kljucna beseda {@code then}.
*/
THEN, THEN,
/** Kljucna beseda {@code else}. */ /**
* Kljucna beseda {@code else}.
*/
ELSE, ELSE,
/** Kljucna beseda {@code while}. */ /**
* Kljucna beseda {@code while}.
*/
WHILE, WHILE,
/** Kljucna beseda {@code do}. */ /**
* Kljucna beseda {@code do}.
*/
DO, DO,
/** Kljucna beseda {@code let}. */ /**
* Kljucna beseda {@code let}.
*/
LET, LET,
/** Kljucna beseda {@code in}. */ /**
* Kljucna beseda {@code in}.
*/
IN, IN,
/** Kljucna beseda {@code end}. */ /**
* Kljucna beseda {@code end}.
*/
END, END,
/** Simbol {@code =}. */ /**
* Simbol {@code =}.
*/
ASSIGN, ASSIGN,
/** Simbol {@code ,}. */ /**
* Simbol {@code ,}.
*/
COMMA, COMMA,
/** Simbol {@code &&}. */ /**
* Simbol {@code &&}.
*/
AND, AND,
/** Simbol {@code ||}. */ /**
* Simbol {@code ||}.
*/
OR, OR,
/** Simbol {@code !}. */ /**
* Simbol {@code !}.
*/
NOT, NOT,
/** Simbol {@code ==}. */ /**
* Simbol {@code ==}.
*/
EQU, EQU,
/** Simbol {@code !=}. */ /**
* Simbol {@code !=}.
*/
NEQ, NEQ,
/** Simbol {@code >}. */ /**
* Simbol {@code >}.
*/
GTH, GTH,
/** Simbol {@code <}. */ /**
* Simbol {@code <}.
*/
LTH, LTH,
/** Simbol {@code >=}. */ /**
* Simbol {@code >=}.
*/
GEQ, GEQ,
/** Simbol {@code <=}. */ /**
* Simbol {@code <=}.
*/
LEQ, LEQ,
/** Simbol {@code +}. */ /**
* Simbol {@code +}.
*/
ADD, ADD,
/** Simbol {@code -}. */ /**
* Simbol {@code -}.
*/
SUB, SUB,
/** Simbol {@code *}. */ /**
* Simbol {@code *}.
*/
MUL, MUL,
/** Simbol {@code /}. */ /**
* Simbol {@code /}.
*/
DIV, DIV,
/** Simbol {@code %}. */ /**
* Simbol {@code %}.
*/
MOD, MOD,
/** Simbol {@code ^}. */ /**
* Simbol {@code ^}.
*/
PTR, PTR,
/** Simbol {@code (}. */ /**
* Simbol {@code (}.
*/
LPAREN, LPAREN,
/** Simbol {@code )}. */ /**
RPAREN, * Simbol {@code )}.
*/
RPAREN;
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 @Override
public String toString() { public String toString() {
String lexeme = switch (symbol) { String lexeme = switch (symbol) {
case INTCONST -> "(" + this.lexeme + ")"; case INTCONST, IDENTIFIER, CHARCONST, STRINGCONST -> "(" + this.lexeme + ")";
case CHARCONST -> "(" + this.lexeme + ")";
case STRINGCONST -> "(" + this.lexeme + ")";
case IDENTIFIER -> "(" + this.lexeme + ")";
default -> ""; default -> "";
}; };
return location + " " + symbol + lexeme; return location + " " + symbol + lexeme;

View File

@ -38,7 +38,7 @@ public class SynAn implements AutoCloseable {
private Token check(Token.Symbol symbol) { private Token check(Token.Symbol symbol) {
final Token token = lexAn.takeToken(); final Token token = lexAn.takeToken();
if (token.symbol() != symbol) 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; return token;
} }
@ -54,21 +54,26 @@ public class SynAn implements AutoCloseable {
} }
private void parseProgram() { private void parseProgram() {
System.out.println("program -> definition restdefs");
parseDefinition(); parseDefinition();
parseRestDefinitions(); parseRestDefinitions();
} }
private void parseRestDefinitions() { private void parseRestDefinitions() {
if (lexAn.peekToken().symbol() != Token.Symbol.EOF) { if (lexAn.peekToken().symbol() != Token.Symbol.EOF) {
System.out.println("restdefs -> definition restdefs");
parseDefinition(); parseDefinition();
parseRestDefinitions(); parseRestDefinitions();
} else {
System.out.println("restdefs -> ε");
} }
} }
private void parseDefinition() { private void parseDefinition() {
Token token = lexAn.peekToken(); Token token = lexAn.peekToken();
switch (token.symbol()) { 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.FUN);
check(Token.Symbol.IDENTIFIER); check(Token.Symbol.IDENTIFIER);
check(Token.Symbol.LPAREN); check(Token.Symbol.LPAREN);
@ -77,7 +82,8 @@ public class SynAn implements AutoCloseable {
parseFunctionAssignment(); parseFunctionAssignment();
break; break;
case Token.Symbol.VAR: case VAR:
System.out.println("definition -> VAR IDENTIFIER ASSIGN initializers");
check(Token.Symbol.VAR); check(Token.Symbol.VAR);
check(Token.Symbol.IDENTIFIER); check(Token.Symbol.IDENTIFIER);
check(Token.Symbol.ASSIGN); check(Token.Symbol.ASSIGN);
@ -91,78 +97,80 @@ public class SynAn implements AutoCloseable {
private void parseFunctionAssignment() { private void parseFunctionAssignment() {
Token token = lexAn.peekToken(); Token token = lexAn.peekToken();
switch (token.symbol()) { if (token.symbol() == Token.Symbol.ASSIGN) {
case Token.Symbol.FUN: System.out.println("funcassign -> ASSIGN statements");
case Token.Symbol.VAR:
case Token.Symbol.IN:
case Token.Symbol.EOF:
break;
case Token.Symbol.ASSIGN:
check(Token.Symbol.ASSIGN); check(Token.Symbol.ASSIGN);
parseStatements(); parseStatements();
break; } else {
System.out.println("funcassign -> ε");
default:
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected ASSIGN.");
} }
} }
private void parseParameters() { private void parseParameters() {
Token token = lexAn.peekToken(); Token token = lexAn.peekToken();
switch (token.symbol()) { if (token.symbol() == Token.Symbol.IDENTIFIER) {
case Token.Symbol.IDENTIFIER: System.out.println("parameters -> IDENTIFIER restparams");
check(Token.Symbol.IDENTIFIER); check(Token.Symbol.IDENTIFIER);
parseRestParameters(); parseRestParameters();
break; } else {
System.out.println("parameters -> ε");
case Token.Symbol.RPAREN:
break;
default:
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected IDENTIFIER or RPAREN.");
} }
} }
private void parseRestParameters() { private void parseRestParameters() {
Token token = lexAn.peekToken(); Token token = lexAn.peekToken();
switch (token.symbol()) { if (token.symbol() == Token.Symbol.COMMA) {
case Token.Symbol.RPAREN: System.out.println("restparams -> COMMA IDENTIFIER restparams");
break;
case Token.Symbol.COMMA:
check(Token.Symbol.COMMA); check(Token.Symbol.COMMA);
check(Token.Symbol.IDENTIFIER); check(Token.Symbol.IDENTIFIER);
parseRestParameters(); parseRestParameters();
break; } else {
System.out.println("restparams -> ε");
default:
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected ')' or ','.");
} }
} }
private void parseStatements() { private void parseStatements() {
System.out.println("statements -> statement reststmts");
parseStatement(); parseStatement();
parseRestStatements(); 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() { private void parseStatement() {
Token token = lexAn.peekToken(); Token token = lexAn.peekToken();
switch (token.symbol()) { switch (token.symbol()) {
case Token.Symbol.IDENTIFIER: case IF:
case Token.Symbol.LPAREN: System.out.println("statement -> if expression then statements elsestmt end");
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:
check(Token.Symbol.IF); check(Token.Symbol.IF);
parseExpression(); parseExpression();
check(Token.Symbol.THEN); check(Token.Symbol.THEN);
@ -171,7 +179,8 @@ public class SynAn implements AutoCloseable {
check(Token.Symbol.END); check(Token.Symbol.END);
break; break;
case Token.Symbol.WHILE: case WHILE:
System.out.println("statement -> while expression do statements end");
check(Token.Symbol.WHILE); check(Token.Symbol.WHILE);
parseExpression(); parseExpression();
check(Token.Symbol.DO); check(Token.Symbol.DO);
@ -179,7 +188,8 @@ public class SynAn implements AutoCloseable {
check(Token.Symbol.END); check(Token.Symbol.END);
break; break;
case Token.Symbol.LET: case LET:
System.out.println("statement -> let definition reststmtdefs in statements end");
check(Token.Symbol.LET); check(Token.Symbol.LET);
parseDefinition(); parseDefinition();
parseRestStatementDefinitions(); parseRestStatementDefinitions();
@ -187,33 +197,318 @@ public class SynAn implements AutoCloseable {
parseStatements(); parseStatements();
check(Token.Symbol.END); check(Token.Symbol.END);
break; break;
}
}
private void parseRestStatements() { default:
if (lexAn.peekToken().symbol() == Token.Symbol.COMMA) { System.out.println("statement -> expression exprassign");
check(Token.Symbol.COMMA); parseExpression();
parseStatements(); parseExpressionAssign();
} }
} }
private void parseRestStatementDefinitions() { 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() { 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() { 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 --- // --- ZAGON ---
/** /**