Finished SynAn without good errors
This commit is contained in:
parent
b1e61398a6
commit
a94802b571
7
.idea/inspectionProfiles/Project_Default.xml
generated
7
.idea/inspectionProfiles/Project_Default.xml
generated
@ -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
8
.idea/misc.xml
generated
@ -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
53
generate.py
Normal 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)
|
50
grammar.txt
50
grammar.txt
@ -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 .
|
6
pns.iml
6
pns.iml
@ -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
35
prg/pass.pins
Normal 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
|
@ -1,2 +0,0 @@
|
|||||||
fun test(a, b,,) =
|
|
||||||
var c = 0
|
|
@ -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;
|
||||||
|
@ -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 ---
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user