AST
This commit is contained in:
parent
a4773edb76
commit
a8f08725aa
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,3 @@
|
|||||||
out/
|
out/
|
||||||
|
|
||||||
**/.DS_Store
|
**/.DS_Store
|
||||||
|
*.zip
|
1
.idea/misc.xml
generated
1
.idea/misc.xml
generated
@ -1,4 +1,3 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="Black">
|
<component name="Black">
|
||||||
<option name="sdkName" value="Python 3.12" />
|
<option name="sdkName" value="Python 3.12" />
|
||||||
|
6
pns.iml
6
pns.iml
@ -1,10 +1,5 @@
|
|||||||
<?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$">
|
||||||
@ -12,6 +7,5 @@
|
|||||||
</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>
|
@ -1,2 +0,0 @@
|
|||||||
fun a() =
|
|
||||||
!+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2>3) || (1<=2) && 1 >= c))^^^^^
|
|
@ -1,4 +0,0 @@
|
|||||||
fun a() =
|
|
||||||
while 1 then
|
|
||||||
neki
|
|
||||||
end
|
|
@ -1,24 +0,0 @@
|
|||||||
var _kfoai = 8 * "neki"
|
|
||||||
var fkaio92j0a = 1 * 'a'
|
|
||||||
|
|
||||||
fun a (c,dvv,d,f,d)
|
|
||||||
fun a() =
|
|
||||||
if !+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^ then
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as
|
|
||||||
else
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as
|
|
||||||
end
|
|
||||||
|
|
||||||
while !+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^ do
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as
|
|
||||||
end
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
fun a() =
|
|
@ -1,2 +0,0 @@
|
|||||||
fun a() =
|
|
||||||
1,2,
|
|
@ -1,26 +0,0 @@
|
|||||||
fun a() =
|
|
||||||
|
|
||||||
let var a = 1 in 1 end,
|
|
||||||
|
|
||||||
let fun a (c,dvv,d,f,d)=
|
|
||||||
!+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^,
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as,
|
|
||||||
|
|
||||||
if !+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^ then
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as
|
|
||||||
end,
|
|
||||||
var a = 10 * "wawawaw"
|
|
||||||
fun b() fun c(a,a,v) in
|
|
||||||
!+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^,
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as
|
|
||||||
end
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
|||||||
fun a() =
|
|
||||||
|
|
||||||
let var a = 1 in 1 end,
|
|
||||||
|
|
||||||
let fun a (c,dvv,d,f,d)=
|
|
||||||
!+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^,
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as,
|
|
||||||
|
|
||||||
if !+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^ then
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as
|
|
||||||
end
|
|
||||||
var a = 10 * "wawawaw"
|
|
||||||
fun b(), fun c(a,a,v) in
|
|
||||||
!+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^,
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as
|
|
||||||
end
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
var a = "10" * "msl"
|
|
@ -1 +0,0 @@
|
|||||||
var a = "10" * 10
|
|
@ -1 +0,0 @@
|
|||||||
fun a(b,1)
|
|
@ -1,2 +0,0 @@
|
|||||||
fun a() =
|
|
||||||
nka(aka(a((1 != 2 && 1/a%e+2-f/d*sa = (1 != 2 && 1/a%e+2-f/d*sa)))
|
|
@ -1,2 +0,0 @@
|
|||||||
fun a() =
|
|
||||||
a==b==c
|
|
@ -1 +0,0 @@
|
|||||||
var a = 10 + "a"
|
|
@ -1,2 +0,0 @@
|
|||||||
fun a =
|
|
||||||
1
|
|
@ -1 +0,0 @@
|
|||||||
var a = 1 + 1
|
|
@ -1 +0,0 @@
|
|||||||
fun a(g,d,d,g,g,f,,gf)
|
|
@ -1,4 +0,0 @@
|
|||||||
fun a() =
|
|
||||||
1,
|
|
||||||
2
|
|
||||||
3
|
|
@ -1,3 +0,0 @@
|
|||||||
fun a() =
|
|
||||||
1//komentar,
|
|
||||||
2
|
|
@ -1,6 +0,0 @@
|
|||||||
fun a() =
|
|
||||||
if !+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^ then
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as
|
|
@ -1,44 +0,0 @@
|
|||||||
var _kfoai = 8 * "neki"
|
|
||||||
var fkaio92j0a = 1 * 'a'
|
|
||||||
|
|
||||||
fun a (c,dvv,d,f,d)
|
|
||||||
|
|
||||||
fun b() =
|
|
||||||
1
|
|
||||||
|
|
||||||
fun a() =
|
|
||||||
!+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^,
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as,
|
|
||||||
nka(aka(a(1 != 2 && 1/a%e+2-f/d*sa, (1 != 2 && 1/a%e+2-f/d*sa)))) = 1 != 2 && 1/a%e+2-f/d*sa,
|
|
||||||
nka(aka(a(1 != 2 && 1/a%e+2-f/d*sa, (1 != 2 && 1/a%e+2-f/d*sa))), njc(1+'a')) = 1 != 2 && 1/a%e+2-f/d*sa,
|
|
||||||
|
|
||||||
if !+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^ then
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as
|
|
||||||
end,
|
|
||||||
|
|
||||||
if !+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^ then
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as
|
|
||||||
else
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as
|
|
||||||
end
|
|
||||||
|
|
||||||
,while !+-^+++(a-n()||b==(1 != (2 && 1)/a%(e+a()-2+mkla(a,g,"kof"-"string"%3+'j'&&2))-f/d*sa && osid*'a' < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^ do
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
|||||||
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, 4 * 'a'
|
|
||||||
var f = 1 * 3
|
|
||||||
var g = 1 * 'a'
|
|
||||||
var h = 4 * "aaa"
|
|
||||||
var i =
|
|
||||||
|
|
||||||
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,
|
|
||||||
!+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^
|
|
@ -1,26 +0,0 @@
|
|||||||
fun a() =
|
|
||||||
|
|
||||||
let var a = 1 in 1 end,
|
|
||||||
|
|
||||||
let fun a (c,dvv,d,f,d)=
|
|
||||||
!+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^,
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as,
|
|
||||||
|
|
||||||
if !+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^ then
|
|
||||||
mfksa(arg1, arg2) = kdoisk(),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as
|
|
||||||
end
|
|
||||||
var a = 10 * "wawawaw"
|
|
||||||
fun b() fun c(a,a,v) in
|
|
||||||
!+-^+++(a||b==(1 != 2 && 1/a%e+2-f/d*sa < (2 && 3) || (1>2) || (1<=2) && 1 >= c))^^^^^,
|
|
||||||
mfksa(arg1, arg2) = kdoisk(a(1)),
|
|
||||||
kajs(a,c,c,1,4,(1+2)&&9^^),
|
|
||||||
a,// komentar
|
|
||||||
_kpofad29-a0as
|
|
||||||
end
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
for file in *.pins25; do
|
|
||||||
echo "Running $file"
|
|
||||||
java ../../src/pins25/phase/SynAn.java "$file" 2>&1 | tail -n 1
|
|
||||||
printf "\n"
|
|
||||||
done
|
|
@ -1,2 +1,7 @@
|
|||||||
fun a() =
|
fun uwu(a) =
|
||||||
1 +
|
let
|
||||||
|
var a = 1
|
||||||
|
var b = 2
|
||||||
|
in
|
||||||
|
a + b
|
||||||
|
end
|
1379
src/pins25/common/AST.java
Normal file
1379
src/pins25/common/AST.java
Normal file
File diff suppressed because it is too large
Load Diff
116
src/pins25/phase/Abstr.java
Normal file
116
src/pins25/phase/Abstr.java
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
package pins25.phase;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import pins25.common.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstraktna sintaksa.
|
||||||
|
*/
|
||||||
|
public class Abstr {
|
||||||
|
|
||||||
|
@SuppressWarnings({"doclint:missing"})
|
||||||
|
public Abstr(SynAn synAn) {
|
||||||
|
throw new Report.InternalError();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstraktno sintaksno drevo z dodanimi atributi abstraktne sintakse.
|
||||||
|
* <p>
|
||||||
|
* Dodani atributi:
|
||||||
|
* <ol>
|
||||||
|
* <li>({@link Abstr}) lokacija kode, ki pripada posameznemu vozliscu.</li>
|
||||||
|
* </ol>
|
||||||
|
*/
|
||||||
|
public static class AttrAST extends AST.AttrAST {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atribut: lokacija kode, ki priprada posameznemu vozliscu.
|
||||||
|
*/
|
||||||
|
public final Map<AST.Node, Report.Locatable> attrLoc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ustvari novo abstraktno sintaksno drevo z dodanimi atributi abstraktne
|
||||||
|
* sintakse.
|
||||||
|
*
|
||||||
|
* @param attrAST Abstraktno sintaksno drevo.
|
||||||
|
* @param attrLoc Atribut: lokacija kode, ki priprada posameznemu vozliscu.
|
||||||
|
*/
|
||||||
|
public AttrAST(final AST.AttrAST attrAST, final Map<AST.Node, Report.Locatable> attrLoc) {
|
||||||
|
super(attrAST.ast);
|
||||||
|
this.attrLoc = attrLoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ustvari novo abstraktno sintaksno drevo z dodanimi atributi abstraktne
|
||||||
|
* sintakse.
|
||||||
|
*
|
||||||
|
* @param attrAST Abstraktno sintaksno drevo z dodanimi atributi abstraktne
|
||||||
|
* sintakse.
|
||||||
|
*/
|
||||||
|
public AttrAST(final AttrAST attrAST) {
|
||||||
|
super(attrAST.ast);
|
||||||
|
this.attrLoc = attrAST.attrLoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String head(final AST.Node node, final boolean highlighted) {
|
||||||
|
switch (node) {
|
||||||
|
case AST.Nodes<?> nodes:
|
||||||
|
return "";
|
||||||
|
default:
|
||||||
|
final Report.Locatable loc = attrLoc.get(node);
|
||||||
|
return (" ") + (loc == null ? "???" : loc.location().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* S klicem sintaksnega analizatorja zgradi abstraktno sintaksno drevo.
|
||||||
|
*
|
||||||
|
* @param synAn Sintaksni analizator.
|
||||||
|
* @return Abstraktno sintaksno drevo z dodanimi atributi abstraktne sintakse.
|
||||||
|
*/
|
||||||
|
public static AttrAST constructAST(SynAn synAn) {
|
||||||
|
final HashMap<AST.Node, Report.Locatable> attrLoc = new HashMap<AST.Node, Report.Locatable>();
|
||||||
|
final AST.Node ast = synAn.parse(attrLoc);
|
||||||
|
return new AttrAST(new AST.AttrAST(ast), Collections.unmodifiableMap(attrLoc));
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- ZAGON ---
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zagon gradnje abstraktnega sintaksnega drevesa kot samostojnega programa.
|
||||||
|
*
|
||||||
|
* @param cmdLineArgs Argumenti v ukazni vrstici.
|
||||||
|
*/
|
||||||
|
public static void main(final String[] cmdLineArgs) {
|
||||||
|
System.out.println("This is PINS'25 compiler (abstract syntax):");
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (cmdLineArgs.length == 0)
|
||||||
|
throw new Report.Error("No source file specified in the command line.");
|
||||||
|
if (cmdLineArgs.length > 1)
|
||||||
|
Report.warning("Unused arguments in the command line.");
|
||||||
|
|
||||||
|
try (final SynAn synAn = new SynAn(cmdLineArgs[0])) {
|
||||||
|
// abstraktna sintaksa:
|
||||||
|
final AttrAST abstrAttrAST = Abstr.constructAST(synAn);
|
||||||
|
|
||||||
|
(new AST.Logger(abstrAttrAST)).log();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upajmo, da kdaj pridemo to te tocke.
|
||||||
|
// A zavedajmo se sledecega:
|
||||||
|
// 1. Prevod je zaradi napak v programu lahko napacen :-o
|
||||||
|
// 2. Izvorni program se zdalec ni tisto, kar je programer hotel, da bi bil ;-)
|
||||||
|
Report.info("Done.");
|
||||||
|
} catch (Report.Error error) {
|
||||||
|
// Izpis opisa napake.
|
||||||
|
System.err.println(error.getMessage());
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,7 +2,9 @@ package pins25.phase;
|
|||||||
|
|
||||||
import pins25.common.*;
|
import pins25.common.*;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sintaksni analizator.
|
* Sintaksni analizator.
|
||||||
@ -14,6 +16,8 @@ public class SynAn implements AutoCloseable {
|
|||||||
*/
|
*/
|
||||||
private final LexAn lexAn;
|
private final LexAn lexAn;
|
||||||
|
|
||||||
|
private HashMap<AST.Node, Report.Locatable> attrLoc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ustvari nov sintaksni analizator.
|
* Ustvari nov sintaksni analizator.
|
||||||
*
|
*
|
||||||
@ -45,158 +49,199 @@ public class SynAn implements AutoCloseable {
|
|||||||
/**
|
/**
|
||||||
* Opravi sintaksno analizo.
|
* Opravi sintaksno analizo.
|
||||||
*/
|
*/
|
||||||
public void parse() {
|
public AST.Node parse(HashMap<AST.Node, Report.Locatable> attrLoc) {
|
||||||
parseProgram();
|
this.attrLoc = attrLoc;
|
||||||
|
final AST.Nodes<AST.MainDef> defs = parseProgram();
|
||||||
if (lexAn.peekToken().symbol() != Token.Symbol.EOF)
|
if (lexAn.peekToken().symbol() != Token.Symbol.EOF)
|
||||||
Report.warning(lexAn.peekToken(),
|
Report.warning(lexAn.peekToken(),
|
||||||
"Unexpected text '" + lexAn.peekToken().lexeme() + "...' at the end of the program.");
|
"Unexpected text '" + lexAn.peekToken().lexeme() + "...' at the end of the program.");
|
||||||
|
return defs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseProgram() {
|
private AST.Nodes<AST.MainDef> parseProgram() {
|
||||||
System.out.println("program -> definition restdefs");
|
// program -> definition restdefs
|
||||||
parseDefinition();
|
List<AST.MainDef> defs = new ArrayList<>();
|
||||||
parseRestDefinitions();
|
|
||||||
|
defs.add(parseDefinition());
|
||||||
|
parseRestDefinitions(defs);
|
||||||
|
|
||||||
|
return new AST.Nodes<>(defs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseRestDefinitions() {
|
private void parseRestDefinitions(List<AST.MainDef> defs) {
|
||||||
if (lexAn.peekToken().symbol() != Token.Symbol.EOF) {
|
if (lexAn.peekToken().symbol() != Token.Symbol.EOF) {
|
||||||
System.out.println("restdefs -> definition restdefs");
|
// restdefs -> definition restdefs
|
||||||
parseDefinition();
|
defs.add(parseDefinition());
|
||||||
parseRestDefinitions();
|
parseRestDefinitions(defs);
|
||||||
} else {
|
|
||||||
System.out.println("restdefs -> ε");
|
|
||||||
}
|
}
|
||||||
|
// restdefs -> ε
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseDefinition() {
|
private AST.MainDef parseDefinition() {
|
||||||
Token token = lexAn.peekToken();
|
Token token = lexAn.peekToken();
|
||||||
switch (token.symbol()) {
|
switch (token.symbol()) {
|
||||||
case FUN:
|
case FUN: {
|
||||||
System.out.println("definition -> FUN IDENTIFIER LPAREN parameters RPAREN funcassign");
|
// definition -> FUN IDENTIFIER LPAREN parameters RPAREN funcassign
|
||||||
check(Token.Symbol.FUN);
|
Token fun = check(Token.Symbol.FUN);
|
||||||
check(Token.Symbol.IDENTIFIER);
|
Token id = check(Token.Symbol.IDENTIFIER);
|
||||||
check(Token.Symbol.LPAREN);
|
check(Token.Symbol.LPAREN);
|
||||||
parseParameters();
|
List<AST.ParDef> params = parseParameters();
|
||||||
check(Token.Symbol.RPAREN);
|
Token rParen = check(Token.Symbol.RPAREN);
|
||||||
parseFunctionAssignment();
|
List<AST.Stmt> stmts = parseFunctionAssignment();
|
||||||
break;
|
|
||||||
|
|
||||||
case VAR:
|
AST.FunDef funDef = new AST.FunDef(id.lexeme(), params, stmts);
|
||||||
System.out.println("definition -> VAR IDENTIFIER ASSIGN initializers");
|
attrLoc.put(funDef, new Report.Location(fun, stmts.isEmpty() ? rParen : attrLoc.get(stmts.getLast())));
|
||||||
check(Token.Symbol.VAR);
|
return funDef;
|
||||||
check(Token.Symbol.IDENTIFIER);
|
}
|
||||||
|
|
||||||
|
case VAR: {
|
||||||
|
// definition -> VAR IDENTIFIER ASSIGN initializers
|
||||||
|
Token var = check(Token.Symbol.VAR);
|
||||||
|
Token id = check(Token.Symbol.IDENTIFIER);
|
||||||
check(Token.Symbol.ASSIGN);
|
check(Token.Symbol.ASSIGN);
|
||||||
parseInitializers();
|
List<AST.Init> inits = parseInitializers();
|
||||||
break;
|
|
||||||
|
AST.VarDef varDef = new AST.VarDef(id.lexeme(), inits);
|
||||||
|
attrLoc.put(varDef, new Report.Location(var, attrLoc.get(inits.getLast())));
|
||||||
|
return varDef;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected definition.");
|
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected definition.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseFunctionAssignment() {
|
private List<AST.Stmt> parseFunctionAssignment() {
|
||||||
Token token = lexAn.peekToken();
|
Token token = lexAn.peekToken();
|
||||||
if (token.symbol() == Token.Symbol.ASSIGN) {
|
if (token.symbol() == Token.Symbol.ASSIGN) {
|
||||||
System.out.println("funcassign -> ASSIGN statements");
|
// funcassign -> ASSIGN statements
|
||||||
check(Token.Symbol.ASSIGN);
|
check(Token.Symbol.ASSIGN);
|
||||||
parseStatements();
|
return parseStatements();
|
||||||
} else {
|
|
||||||
System.out.println("funcassign -> ε");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseParameters() {
|
// funcassign -> ε
|
||||||
|
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AST.ParDef> parseParameters() {
|
||||||
|
List<AST.ParDef> defs = new ArrayList<>();
|
||||||
Token token = lexAn.peekToken();
|
Token token = lexAn.peekToken();
|
||||||
if (token.symbol() == Token.Symbol.IDENTIFIER) {
|
if (token.symbol() == Token.Symbol.IDENTIFIER) {
|
||||||
System.out.println("parameters -> IDENTIFIER restparams");
|
// parameters -> IDENTIFIER restparams
|
||||||
check(Token.Symbol.IDENTIFIER);
|
Token id = check(Token.Symbol.IDENTIFIER);
|
||||||
parseRestParameters();
|
AST.ParDef parDef = new AST.ParDef(id.lexeme());
|
||||||
} else {
|
attrLoc.put(parDef, id);
|
||||||
System.out.println("parameters -> ε");
|
defs.add(parDef);
|
||||||
}
|
parseRestParameters(defs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseRestParameters() {
|
// parameters -> ε
|
||||||
|
|
||||||
|
return defs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseRestParameters(List<AST.ParDef> defs) {
|
||||||
Token token = lexAn.peekToken();
|
Token token = lexAn.peekToken();
|
||||||
if (token.symbol() == Token.Symbol.COMMA) {
|
if (token.symbol() == Token.Symbol.COMMA) {
|
||||||
System.out.println("restparams -> COMMA IDENTIFIER restparams");
|
// restparams -> COMMA IDENTIFIER restparams
|
||||||
check(Token.Symbol.COMMA);
|
check(Token.Symbol.COMMA);
|
||||||
check(Token.Symbol.IDENTIFIER);
|
Token id = check(Token.Symbol.IDENTIFIER);
|
||||||
parseRestParameters();
|
AST.ParDef parDef = new AST.ParDef(id.lexeme());
|
||||||
} else {
|
attrLoc.put(parDef, id);
|
||||||
System.out.println("restparams -> ε");
|
defs.add(parDef);
|
||||||
|
parseRestParameters(defs);
|
||||||
}
|
}
|
||||||
|
// restparams -> ε
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseStatements() {
|
private List<AST.Stmt> parseStatements() {
|
||||||
System.out.println("statements -> statement reststmts");
|
// statements -> statement reststmts
|
||||||
parseStatement();
|
|
||||||
parseRestStatements();
|
List<AST.Stmt> stmts = new ArrayList<>();
|
||||||
|
|
||||||
|
stmts.add(parseStatement());
|
||||||
|
parseRestStatements(stmts);
|
||||||
|
|
||||||
|
return stmts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseExpressionAssign() {
|
private AST.Expr parseExpressionAssign() {
|
||||||
if (lexAn.peekToken().symbol() == Token.Symbol.ASSIGN) {
|
if (lexAn.peekToken().symbol() == Token.Symbol.ASSIGN) {
|
||||||
System.out.println("exprassign -> ASSIGN expression");
|
// exprassign -> ASSIGN expression
|
||||||
check(Token.Symbol.ASSIGN);
|
check(Token.Symbol.ASSIGN);
|
||||||
parseExpression();
|
return parseExpression();
|
||||||
} else {
|
|
||||||
System.out.println("exprassign -> ε");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseElseStatement() {
|
// exprassign -> ε
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AST.Stmt> parseElseStatements() {
|
||||||
if (lexAn.peekToken().symbol() == Token.Symbol.ELSE) {
|
if (lexAn.peekToken().symbol() == Token.Symbol.ELSE) {
|
||||||
System.out.println("elsestmt -> ELSE statements");
|
// elsestmt -> ELSE statements
|
||||||
check(Token.Symbol.ELSE);
|
check(Token.Symbol.ELSE);
|
||||||
parseStatements();
|
return parseStatements();
|
||||||
} else {
|
|
||||||
System.out.println("elsestmt -> ε");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseRestStatements() {
|
// elsestmt -> ε
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseRestStatements(List<AST.Stmt> stmts) {
|
||||||
if (lexAn.peekToken().symbol() == Token.Symbol.COMMA) {
|
if (lexAn.peekToken().symbol() == Token.Symbol.COMMA) {
|
||||||
System.out.println("reststmts -> COMMA statement reststmts");
|
// reststmts -> COMMA statement reststmts
|
||||||
check(Token.Symbol.COMMA);
|
check(Token.Symbol.COMMA);
|
||||||
parseStatement();
|
stmts.add(parseStatement());
|
||||||
parseRestStatements();
|
parseRestStatements(stmts);
|
||||||
} else {
|
|
||||||
System.out.println("reststmts -> ε");
|
|
||||||
}
|
}
|
||||||
|
// reststmts -> ε
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseStatement() {
|
private AST.Stmt parseStatement() {
|
||||||
Token token = lexAn.peekToken();
|
Token token = lexAn.peekToken();
|
||||||
switch (token.symbol()) {
|
switch (token.symbol()) {
|
||||||
case IF:
|
case IF: {
|
||||||
System.out.println("statement -> if expression then statements elsestmt end");
|
// statement -> if expression then statements elsestmt end
|
||||||
check(Token.Symbol.IF);
|
Token ifT = check(Token.Symbol.IF);
|
||||||
parseExpression();
|
AST.Expr cond = parseExpression();
|
||||||
check(Token.Symbol.THEN);
|
check(Token.Symbol.THEN);
|
||||||
parseStatements();
|
List<AST.Stmt> thenStmts = parseStatements();
|
||||||
parseElseStatement();
|
List<AST.Stmt> elseStmts = parseElseStatements();
|
||||||
check(Token.Symbol.END);
|
Token end = check(Token.Symbol.END);
|
||||||
break;
|
|
||||||
|
|
||||||
case WHILE:
|
AST.IfStmt ifStmt = new AST.IfStmt(cond, thenStmts, elseStmts);
|
||||||
System.out.println("statement -> while expression do statements end");
|
attrLoc.put(ifStmt, new Report.Location(ifT, end));
|
||||||
check(Token.Symbol.WHILE);
|
return ifStmt;
|
||||||
parseExpression();
|
}
|
||||||
|
|
||||||
|
case WHILE: {
|
||||||
|
// statement -> while expression do statements end
|
||||||
|
Token whileT = check(Token.Symbol.WHILE);
|
||||||
|
AST.Expr cond = parseExpression();
|
||||||
check(Token.Symbol.DO);
|
check(Token.Symbol.DO);
|
||||||
parseStatements();
|
List<AST.Stmt> stmts = parseStatements();
|
||||||
check(Token.Symbol.END);
|
Token end = check(Token.Symbol.END);
|
||||||
break;
|
|
||||||
|
|
||||||
case LET:
|
AST.WhileStmt whileStmt = new AST.WhileStmt(cond, stmts);
|
||||||
System.out.println("statement -> let definition reststmtdefs in statements end");
|
attrLoc.put(whileStmt, new Report.Location(whileT, end));
|
||||||
check(Token.Symbol.LET);
|
return whileStmt;
|
||||||
parseDefinition();
|
}
|
||||||
parseRestStatementDefinitions();
|
|
||||||
|
case LET: {
|
||||||
|
// statement -> let definition reststmtdefs in statements end
|
||||||
|
Token let = check(Token.Symbol.LET);
|
||||||
|
List<AST.MainDef> defs = new ArrayList<>();
|
||||||
|
defs.add(parseDefinition());
|
||||||
|
parseRestStatementDefinitions(defs);
|
||||||
check(Token.Symbol.IN);
|
check(Token.Symbol.IN);
|
||||||
parseStatements();
|
List<AST.Stmt> stmts = parseStatements();
|
||||||
check(Token.Symbol.END);
|
Token end = check(Token.Symbol.END);
|
||||||
break;
|
|
||||||
|
AST.LetStmt letStmt = new AST.LetStmt(defs, stmts);
|
||||||
|
attrLoc.put(letStmt, new Report.Location(let, end));
|
||||||
|
return letStmt;
|
||||||
|
}
|
||||||
|
|
||||||
case IDENTIFIER:
|
case IDENTIFIER:
|
||||||
case LPAREN:
|
case LPAREN:
|
||||||
@ -207,111 +252,157 @@ public class SynAn implements AutoCloseable {
|
|||||||
case INTCONST:
|
case INTCONST:
|
||||||
case CHARCONST:
|
case CHARCONST:
|
||||||
case STRINGCONST:
|
case STRINGCONST:
|
||||||
System.out.println("statement -> expression exprassign");
|
// statement -> expression exprassign
|
||||||
parseExpression();
|
AST.Expr expr = parseExpression();
|
||||||
parseExpressionAssign();
|
AST.Expr srcExpr = parseExpressionAssign();
|
||||||
break;
|
if (srcExpr != null) {
|
||||||
|
AST.AssignStmt assignStmt = new AST.AssignStmt(expr, srcExpr);
|
||||||
|
attrLoc.put(assignStmt, new Report.Location(attrLoc.get(expr), attrLoc.get(srcExpr)));
|
||||||
|
return assignStmt;
|
||||||
|
}
|
||||||
|
AST.ExprStmt exprStmt = new AST.ExprStmt(expr);
|
||||||
|
attrLoc.put(exprStmt, attrLoc.get(expr));
|
||||||
|
return exprStmt;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected statement.");
|
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected statement.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseRestStatementDefinitions() {
|
private void parseRestStatementDefinitions(List<AST.MainDef> defs) {
|
||||||
switch (lexAn.peekToken().symbol()) {
|
switch (lexAn.peekToken().symbol()) {
|
||||||
case FUN:
|
case FUN:
|
||||||
case VAR:
|
case VAR:
|
||||||
System.out.println("reststmtdefs -> definition reststmtdefs");
|
// reststmtdefs -> definition reststmtdefs
|
||||||
parseDefinition();
|
defs.add(parseDefinition());
|
||||||
parseRestStatementDefinitions();
|
parseRestStatementDefinitions(defs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IN:
|
case IN:
|
||||||
System.out.println("reststmtdefs -> ε");
|
// reststmtdefs -> ε
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseInitializers() {
|
private List<AST.Init> parseInitializers() {
|
||||||
|
List<AST.Init> inits = new ArrayList<>();
|
||||||
|
|
||||||
switch (lexAn.peekToken().symbol()) {
|
switch (lexAn.peekToken().symbol()) {
|
||||||
case INTCONST:
|
case INTCONST:
|
||||||
case CHARCONST:
|
case CHARCONST:
|
||||||
case STRINGCONST:
|
case STRINGCONST:
|
||||||
System.out.println("initializers -> initializer restinits");
|
// initializers -> initializer restinits
|
||||||
parseInitializer();
|
inits.add(parseInitializer());
|
||||||
parseRestInitializers();
|
parseRestInitializers(inits);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
System.out.println("initializers -> ε");
|
// initializers -> ε
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return inits;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseInitializer() {
|
private AST.Init parseInitializer() {
|
||||||
Token token = lexAn.peekToken();
|
Token token = lexAn.peekToken();
|
||||||
switch (token.symbol()) {
|
switch (token.symbol()) {
|
||||||
case INTCONST:
|
case INTCONST: {
|
||||||
System.out.println("initializer -> INTCONST intconstmult");
|
// initializer -> INTCONST intconstmult
|
||||||
check(Token.Symbol.INTCONST);
|
Token value = check(Token.Symbol.INTCONST);
|
||||||
parseIntegerConstantMultiplier();
|
AST.AtomExpr intConst = new AST.AtomExpr(AST.AtomExpr.Type.INTCONST, value.lexeme());
|
||||||
break;
|
attrLoc.put(intConst, value);
|
||||||
|
AST.AtomExpr multConst = parseIntegerConstantMultiplier();
|
||||||
|
if (multConst != null) {
|
||||||
|
AST.Init init = new AST.Init(intConst, multConst);
|
||||||
|
attrLoc.put(init, new Report.Location(value, attrLoc.get(multConst)));
|
||||||
|
return init;
|
||||||
|
}
|
||||||
|
AST.Init init = new AST.Init(
|
||||||
|
new AST.AtomExpr(AST.AtomExpr.Type.INTCONST, "1"),
|
||||||
|
intConst
|
||||||
|
);
|
||||||
|
attrLoc.put(init, value);
|
||||||
|
return init;
|
||||||
|
}
|
||||||
|
|
||||||
case CHARCONST:
|
case CHARCONST: {
|
||||||
System.out.println("initializer -> CHARCONST");
|
// initializer -> CHARCONST
|
||||||
check(Token.Symbol.CHARCONST);
|
Token value = check(Token.Symbol.CHARCONST);
|
||||||
break;
|
AST.AtomExpr charConst = new AST.AtomExpr(AST.AtomExpr.Type.CHRCONST, value.lexeme());
|
||||||
|
attrLoc.put(charConst, value);
|
||||||
|
AST.Init init = new AST.Init(
|
||||||
|
new AST.AtomExpr(AST.AtomExpr.Type.INTCONST, "1"),
|
||||||
|
charConst
|
||||||
|
);
|
||||||
|
attrLoc.put(init, value);
|
||||||
|
return init;
|
||||||
|
}
|
||||||
|
|
||||||
case STRINGCONST:
|
case STRINGCONST: {
|
||||||
System.out.println("initializer -> STRINGCONST");
|
// initializer -> STRINGCONST
|
||||||
check(Token.Symbol.STRINGCONST);
|
Token value = check(Token.Symbol.STRINGCONST);
|
||||||
break;
|
AST.AtomExpr strConst = new AST.AtomExpr(AST.AtomExpr.Type.STRCONST, value.lexeme());
|
||||||
|
attrLoc.put(strConst, value);
|
||||||
|
AST.Init init = new AST.Init(
|
||||||
|
new AST.AtomExpr(AST.AtomExpr.Type.INTCONST, "1"),
|
||||||
|
strConst
|
||||||
|
);
|
||||||
|
attrLoc.put(init, value);
|
||||||
|
return init;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected constant.");
|
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected constant.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseRestInitializers() {
|
private void parseRestInitializers(List<AST.Init> inits) {
|
||||||
Token token = lexAn.peekToken();
|
Token token = lexAn.peekToken();
|
||||||
if (token.symbol() == Token.Symbol.COMMA) {
|
if (token.symbol() == Token.Symbol.COMMA) {
|
||||||
System.out.println("restinits -> COMMA initializer restinits");
|
// restinits -> COMMA initializer restinits
|
||||||
check(Token.Symbol.COMMA);
|
check(Token.Symbol.COMMA);
|
||||||
parseInitializer();
|
inits.add(parseInitializer());
|
||||||
parseRestInitializers();
|
parseRestInitializers(inits);
|
||||||
} else {
|
|
||||||
System.out.println("restinits -> ε");
|
|
||||||
}
|
}
|
||||||
|
// restinits -> ε
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseIntegerConstantMultiplier() {
|
private AST.AtomExpr parseIntegerConstantMultiplier() {
|
||||||
Token token = lexAn.peekToken();
|
Token token = lexAn.peekToken();
|
||||||
if (token.symbol() == Token.Symbol.MUL) {
|
if (token.symbol() == Token.Symbol.MUL) {
|
||||||
System.out.println("intconstmult -> MUL const");
|
// intconstmult -> MUL const
|
||||||
check(Token.Symbol.MUL);
|
check(Token.Symbol.MUL);
|
||||||
parseConstant();
|
return parseConstant();
|
||||||
} else {
|
|
||||||
System.out.println("intconstmult -> ε");
|
|
||||||
}
|
}
|
||||||
|
// intconstmult -> ε
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseConstant() {
|
private AST.AtomExpr parseConstant() {
|
||||||
Token token = lexAn.peekToken();
|
Token token = lexAn.peekToken();
|
||||||
switch (token.symbol()) {
|
switch (token.symbol()) {
|
||||||
case INTCONST:
|
case INTCONST: {
|
||||||
System.out.println("const -> INTCONST");
|
// const -> INTCONST
|
||||||
check(Token.Symbol.INTCONST);
|
Token value = check(Token.Symbol.INTCONST);
|
||||||
break;
|
AST.AtomExpr atomExpr = new AST.AtomExpr(AST.AtomExpr.Type.INTCONST, value.lexeme());
|
||||||
|
attrLoc.put(atomExpr, value);
|
||||||
case CHARCONST:
|
return atomExpr;
|
||||||
System.out.println("const -> CHARCONST");
|
}
|
||||||
check(Token.Symbol.CHARCONST);
|
case CHARCONST: {
|
||||||
break;
|
// const -> CHARCONST
|
||||||
|
Token value = check(Token.Symbol.CHARCONST);
|
||||||
case STRINGCONST:
|
AST.AtomExpr atomExpr = new AST.AtomExpr(AST.AtomExpr.Type.CHRCONST, value.lexeme());
|
||||||
System.out.println("const -> STRINGCONST");
|
attrLoc.put(atomExpr, value);
|
||||||
check(Token.Symbol.STRINGCONST);
|
return atomExpr;
|
||||||
break;
|
}
|
||||||
|
case STRINGCONST: {
|
||||||
|
// const -> STRINGCONST
|
||||||
|
Token value = check(Token.Symbol.STRINGCONST);
|
||||||
|
AST.AtomExpr atomExpr = new AST.AtomExpr(AST.AtomExpr.Type.STRCONST, value.lexeme());
|
||||||
|
attrLoc.put(atomExpr, value);
|
||||||
|
return atomExpr;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected constant.");
|
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected constant.");
|
||||||
@ -337,218 +428,324 @@ public class SynAn implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseExpression() {
|
private AST.Expr parseExpression() {
|
||||||
checkExpression();
|
checkExpression();
|
||||||
|
|
||||||
System.out.println("expression -> conjexpr restdisj");
|
// expression -> conjexpr restdisj
|
||||||
parseConjunctionExpression();
|
AST.Expr left = parseConjunctionExpression();
|
||||||
parseRestDisjunctions();
|
return parseRestDisjunctions(left);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseRestDisjunctions() {
|
private AST.Expr parseRestDisjunctions(AST.Expr left) {
|
||||||
if (lexAn.peekToken().symbol() == Token.Symbol.OR) {
|
if (lexAn.peekToken().symbol() == Token.Symbol.OR) {
|
||||||
System.out.println("restdisj -> OR conjexpr restdisj");
|
// restdisj -> OR conjexpr restdisj
|
||||||
check(Token.Symbol.OR);
|
check(Token.Symbol.OR);
|
||||||
parseConjunctionExpression();
|
AST.Expr right = parseConjunctionExpression();
|
||||||
parseRestDisjunctions();
|
AST.Expr binExpr = new AST.BinExpr(AST.BinExpr.Oper.OR, left, right);
|
||||||
|
attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right)));
|
||||||
|
return parseRestDisjunctions(binExpr);
|
||||||
|
} else {
|
||||||
|
// restdisj -> ε
|
||||||
|
return left;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseConjunctionExpression() {
|
private AST.Expr parseConjunctionExpression() {
|
||||||
checkExpression();
|
checkExpression();
|
||||||
|
|
||||||
System.out.println("conjexpr -> cmpexpr restconj");
|
// conjexpr -> cmpexpr restconj
|
||||||
parseComparisonExpression();
|
AST.Expr left = parseComparisonExpression();
|
||||||
parseRestConjunctionExpressions();
|
return parseRestConjunctions(left);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseRestConjunctionExpressions() {
|
private AST.Expr parseRestConjunctions(AST.Expr left) {
|
||||||
if (lexAn.peekToken().symbol() == Token.Symbol.AND) {
|
if (lexAn.peekToken().symbol() == Token.Symbol.AND) {
|
||||||
System.out.println("restconj -> AND cmpexpr restconj");
|
// restconj -> AND cmpexpr restconj
|
||||||
check(Token.Symbol.AND);
|
check(Token.Symbol.AND);
|
||||||
parseComparisonExpression();
|
AST.Expr right = parseComparisonExpression();
|
||||||
parseRestConjunctionExpressions();
|
AST.Expr binExpr = new AST.BinExpr(AST.BinExpr.Oper.AND, left, right);
|
||||||
|
attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right)));
|
||||||
|
return parseRestConjunctions(binExpr);
|
||||||
} else {
|
} else {
|
||||||
System.out.println("restconj -> ε");
|
// restconj -> ε
|
||||||
|
return left;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseComparisonExpression() {
|
private AST.Expr parseComparisonExpression() {
|
||||||
checkExpression();
|
checkExpression();
|
||||||
|
|
||||||
System.out.println("cmpexpr -> addexpr restcmp");
|
// cmpexpr -> addexpr restcmp
|
||||||
parseAdditionExpression();
|
AST.Expr left = parseAdditionExpression();
|
||||||
parseRestComparisons();
|
return parseRestComparisons(left);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseRestComparisons() {
|
private AST.Expr parseRestComparisons(AST.Expr left) {
|
||||||
Token token = lexAn.peekToken();
|
Token token = lexAn.peekToken();
|
||||||
switch (token.symbol()) {
|
switch (token.symbol()) {
|
||||||
case EQU:
|
case EQU: {
|
||||||
case NEQ:
|
// restcmp -> EQU addexpr
|
||||||
case LTH:
|
check(Token.Symbol.EQU);
|
||||||
case GTH:
|
AST.Expr right = parseAdditionExpression();
|
||||||
case LEQ:
|
AST.BinExpr binExpr = new AST.BinExpr(AST.BinExpr.Oper.EQU, left, right);
|
||||||
case GEQ:
|
attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right)));
|
||||||
System.out.printf("restcmp -> %s addexpr\n", token.symbol());
|
return binExpr;
|
||||||
check(token.symbol());
|
}
|
||||||
parseAdditionExpression();
|
case NEQ: {
|
||||||
break;
|
// restcmp -> NEQ addexpr
|
||||||
|
check(Token.Symbol.NEQ);
|
||||||
|
AST.Expr right = parseAdditionExpression();
|
||||||
|
AST.BinExpr binExpr = new AST.BinExpr(AST.BinExpr.Oper.EQU, left, right);
|
||||||
|
attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right)));
|
||||||
|
return binExpr;
|
||||||
|
}
|
||||||
|
case LTH: {
|
||||||
|
// restcmp -> LTH addexpr
|
||||||
|
check(Token.Symbol.LTH);
|
||||||
|
AST.Expr right = parseAdditionExpression();
|
||||||
|
AST.BinExpr binExpr = new AST.BinExpr(AST.BinExpr.Oper.LTH, left, right);
|
||||||
|
attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right)));
|
||||||
|
return binExpr;
|
||||||
|
}
|
||||||
|
case GTH: {
|
||||||
|
// restcmp -> GTH addexpr
|
||||||
|
check(Token.Symbol.GTH);
|
||||||
|
AST.Expr right = parseAdditionExpression();
|
||||||
|
AST.BinExpr binExpr = new AST.BinExpr(AST.BinExpr.Oper.GTH, left, right);
|
||||||
|
attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right)));
|
||||||
|
return binExpr;
|
||||||
|
}
|
||||||
|
case LEQ: {
|
||||||
|
// restcmp -> LEQ addexpr
|
||||||
|
check(Token.Symbol.LEQ);
|
||||||
|
AST.Expr right = parseAdditionExpression();
|
||||||
|
AST.BinExpr binExpr = new AST.BinExpr(AST.BinExpr.Oper.LEQ, left, right);
|
||||||
|
attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right)));
|
||||||
|
return binExpr;
|
||||||
|
}
|
||||||
|
case GEQ: {
|
||||||
|
// restcmp -> GEQ addexpr
|
||||||
|
check(Token.Symbol.GEQ);
|
||||||
|
AST.Expr right = parseAdditionExpression();
|
||||||
|
AST.BinExpr binExpr = new AST.BinExpr(AST.BinExpr.Oper.GEQ, left, right);
|
||||||
|
attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right)));
|
||||||
|
return binExpr;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
System.out.println("restcmp -> ε");
|
// restcmp -> ε
|
||||||
break;
|
return left;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseAdditionExpression() {
|
private AST.Expr parseAdditionExpression() {
|
||||||
checkExpression();
|
checkExpression();
|
||||||
|
|
||||||
System.out.println("addexpr -> multexpr restadd");
|
// addexpr -> multexpr restadd
|
||||||
parseMultiplicationExpression();
|
AST.Expr left = parseMultiplicationExpression();
|
||||||
parseRestAdditions();
|
return parseRestAdditions(left);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseRestAdditions() {
|
private AST.Expr parseRestAdditions(AST.Expr left) {
|
||||||
Token token = lexAn.peekToken();
|
Token token = lexAn.peekToken();
|
||||||
switch (token.symbol()) {
|
switch (token.symbol()) {
|
||||||
case ADD:
|
case ADD: {
|
||||||
case SUB:
|
// restadd -> ADD multexpr restadd
|
||||||
System.out.printf("restadd -> %s multexpr restadd\n", token.symbol());
|
check(Token.Symbol.ADD);
|
||||||
check(token.symbol());
|
AST.Expr right = parseMultiplicationExpression();
|
||||||
parseMultiplicationExpression();
|
AST.Expr binExpr = new AST.BinExpr(AST.BinExpr.Oper.ADD, left, right);
|
||||||
parseRestAdditions();
|
attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right)));
|
||||||
break;
|
return parseRestAdditions(binExpr);
|
||||||
|
}
|
||||||
|
case SUB: {
|
||||||
|
// restadd -> SUN multexpr restadd
|
||||||
|
check(Token.Symbol.SUB);
|
||||||
|
AST.Expr right = parseMultiplicationExpression();
|
||||||
|
AST.Expr binExpr = new AST.BinExpr(AST.BinExpr.Oper.SUB, left, right);
|
||||||
|
attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right)));
|
||||||
|
return parseRestAdditions(binExpr);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
System.out.println("restadd -> ε");
|
// restadd -> ε
|
||||||
break;
|
return left;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseMultiplicationExpression() {
|
private AST.Expr parseMultiplicationExpression() {
|
||||||
checkExpression();
|
checkExpression();
|
||||||
|
|
||||||
System.out.println("multexpr -> prefixexpr restmult");
|
// multexpr -> prefixexpr restmult
|
||||||
parsePrefixExpression();
|
AST.Expr left = parsePrefixExpression();
|
||||||
parseRestMultiplicationExpressions();
|
return parseRestMultiplicationExpressions(left);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseRestMultiplicationExpressions() {
|
private AST.Expr parseRestMultiplicationExpressions(AST.Expr left) {
|
||||||
Token token = lexAn.peekToken();
|
Token token = lexAn.peekToken();
|
||||||
switch (token.symbol()) {
|
switch (token.symbol()) {
|
||||||
case MUL:
|
case MUL: {
|
||||||
case DIV:
|
// restmult -> MUL prefixexpr restmult
|
||||||
case MOD:
|
check(Token.Symbol.MUL);
|
||||||
System.out.printf("restmult -> %s prefixexpr restmult\n", token.symbol());
|
AST.Expr right = parseMultiplicationExpression();
|
||||||
check(token.symbol());
|
AST.Expr binExpr = new AST.BinExpr(AST.BinExpr.Oper.MUL, left, right);
|
||||||
parsePrefixExpression();
|
attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right)));
|
||||||
parseRestMultiplicationExpressions();
|
return parseRestMultiplicationExpressions(binExpr);
|
||||||
break;
|
}
|
||||||
|
case DIV: {
|
||||||
|
// restmult -> DIV prefixexpr restmult
|
||||||
|
check(Token.Symbol.DIV);
|
||||||
|
AST.Expr right = parseMultiplicationExpression();
|
||||||
|
AST.Expr binExpr = new AST.BinExpr(AST.BinExpr.Oper.DIV, left, right);
|
||||||
|
attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right)));
|
||||||
|
return parseRestMultiplicationExpressions(binExpr);
|
||||||
|
}
|
||||||
|
case MOD: {
|
||||||
|
// restmult -> MOD prefixexpr restmult
|
||||||
|
check(Token.Symbol.MOD);
|
||||||
|
AST.Expr right = parseMultiplicationExpression();
|
||||||
|
AST.Expr binExpr = new AST.BinExpr(AST.BinExpr.Oper.MOD, left, right);
|
||||||
|
attrLoc.put(binExpr, new Report.Location(attrLoc.get(left), attrLoc.get(right)));
|
||||||
|
return parseRestMultiplicationExpressions(binExpr);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
System.out.println("restmult -> ε");
|
// restmult -> ε
|
||||||
break;
|
return left;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parsePrefixExpression() {
|
private AST.Expr parsePrefixExpression() {
|
||||||
checkExpression();
|
checkExpression();
|
||||||
|
|
||||||
Token token = lexAn.peekToken();
|
Token token = lexAn.peekToken();
|
||||||
switch (token.symbol()) {
|
switch (token.symbol()) {
|
||||||
case ADD:
|
case ADD: {
|
||||||
case SUB:
|
// prefixexpr -> ADD prefixexpr
|
||||||
case NOT:
|
Token add = check(Token.Symbol.ADD);
|
||||||
case PTR:
|
AST.Expr prefixExpr = parsePrefixExpression();
|
||||||
System.out.printf("prefixexpr -> %s prefixexpr\n", token.symbol());
|
AST.UnExpr unExpr = new AST.UnExpr(AST.UnExpr.Oper.ADD, prefixExpr);
|
||||||
check(token.symbol());
|
attrLoc.put(unExpr, new Report.Location(add, attrLoc.get(prefixExpr)));
|
||||||
parsePrefixExpression();
|
return unExpr;
|
||||||
break;
|
}
|
||||||
|
case SUB: {
|
||||||
|
// prefixexpr -> SUB prefixexpr
|
||||||
|
Token sub = check(Token.Symbol.SUB);
|
||||||
|
AST.Expr prefixExpr = parsePrefixExpression();
|
||||||
|
AST.UnExpr unExpr = new AST.UnExpr(AST.UnExpr.Oper.SUB, prefixExpr);
|
||||||
|
attrLoc.put(unExpr, new Report.Location(sub, attrLoc.get(prefixExpr)));
|
||||||
|
return unExpr;
|
||||||
|
}
|
||||||
|
case NOT: {
|
||||||
|
// prefixexpr -> NOT prefixexpr
|
||||||
|
Token not = check(Token.Symbol.NOT);
|
||||||
|
AST.Expr prefixExpr = parsePrefixExpression();
|
||||||
|
AST.UnExpr unExpr = new AST.UnExpr(AST.UnExpr.Oper.NOT, prefixExpr);
|
||||||
|
attrLoc.put(unExpr, new Report.Location(not, attrLoc.get(prefixExpr)));
|
||||||
|
return unExpr;
|
||||||
|
}
|
||||||
|
case PTR: {
|
||||||
|
// prefixexpr -> PTR prefixexpr
|
||||||
|
Token ptr = check(Token.Symbol.PTR);
|
||||||
|
AST.Expr prefixExpr = parsePrefixExpression();
|
||||||
|
AST.UnExpr unExpr = new AST.UnExpr(AST.UnExpr.Oper.MEMADDR, prefixExpr);
|
||||||
|
attrLoc.put(unExpr, new Report.Location(ptr, attrLoc.get(prefixExpr)));
|
||||||
|
return unExpr;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
System.out.println("prefixexpr -> postfixexpr");
|
// prefixexpr -> postfixexpr
|
||||||
parsePostfixExpression();
|
return parsePostfixExpression();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parsePostfixExpression() {
|
private AST.Expr parsePostfixExpression() {
|
||||||
checkExpression();
|
checkExpression();
|
||||||
|
|
||||||
System.out.println("postfixexpr -> primary postfixop");
|
// postfixexpr -> primary postfixop
|
||||||
parsePrimary();
|
AST.Expr inner = parsePrimary();
|
||||||
parsePostfixOperator();
|
return parsePostfixOperator(inner);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parsePostfixOperator() {
|
private AST.Expr parsePostfixOperator(AST.Expr inner) {
|
||||||
if (lexAn.peekToken().symbol() == Token.Symbol.PTR) {
|
if (lexAn.peekToken().symbol() == Token.Symbol.PTR) {
|
||||||
System.out.println("postfixop -> PTR postfixop");
|
// postfixop -> PTR postfixop
|
||||||
check(Token.Symbol.PTR);
|
Token ptr = check(Token.Symbol.PTR);
|
||||||
parsePostfixOperator();
|
AST.UnExpr unExpr = new AST.UnExpr(AST.UnExpr.Oper.VALUEAT, inner);
|
||||||
} else {
|
attrLoc.put(unExpr, new Report.Location(attrLoc.get(inner), ptr));
|
||||||
System.out.println("postfixop -> ε");
|
return parsePostfixOperator(unExpr);
|
||||||
}
|
}
|
||||||
|
// postfixop -> ε
|
||||||
|
return inner;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parsePrimary() {
|
private AST.Expr parsePrimary() {
|
||||||
Token token = lexAn.peekToken();
|
Token token = lexAn.peekToken();
|
||||||
switch (token.symbol()) {
|
switch (token.symbol()) {
|
||||||
case IDENTIFIER:
|
case IDENTIFIER:
|
||||||
System.out.println("primary -> IDENTIFIER exprargs");
|
// primary -> IDENTIFIER exprargs
|
||||||
check(Token.Symbol.IDENTIFIER);
|
Token id = check(Token.Symbol.IDENTIFIER);
|
||||||
parseExpressionArguments();
|
List<AST.Expr> args = parseExpressionArguments();
|
||||||
break;
|
if (args != null) {
|
||||||
|
AST.CallExpr callExpr = new AST.CallExpr(id.lexeme(), args);
|
||||||
|
attrLoc.put(callExpr, new Report.Location(id, attrLoc.get(args.getLast())));
|
||||||
|
return callExpr;
|
||||||
|
}
|
||||||
|
AST.VarExpr varExpr = new AST.VarExpr(id.lexeme());
|
||||||
|
attrLoc.put(varExpr, id);
|
||||||
|
return varExpr;
|
||||||
|
|
||||||
case LPAREN:
|
case LPAREN:
|
||||||
System.out.println("primary -> LPAREN expression RPAREN");
|
// primary -> LPAREN expression RPAREN
|
||||||
check(Token.Symbol.LPAREN);
|
check(Token.Symbol.LPAREN);
|
||||||
parseExpression();
|
AST.Expr expr = parseExpression();
|
||||||
check(Token.Symbol.RPAREN);
|
check(Token.Symbol.RPAREN);
|
||||||
break;
|
return expr;
|
||||||
|
|
||||||
case INTCONST:
|
case INTCONST:
|
||||||
case CHARCONST:
|
case CHARCONST:
|
||||||
case STRINGCONST:
|
case STRINGCONST:
|
||||||
System.out.println("primary -> const");
|
// primary -> const
|
||||||
parseConstant();
|
return parseConstant();
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected identifier, constant or '('.");
|
throw new Report.Error(token, "Unexpected symbol '" + token.lexeme() + "', expected identifier, constant or '('.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseExpressionArguments() {
|
private List<AST.Expr> parseExpressionArguments() {
|
||||||
if (lexAn.peekToken().symbol() == Token.Symbol.LPAREN) {
|
if (lexAn.peekToken().symbol() == Token.Symbol.LPAREN) {
|
||||||
System.out.println("exprargs -> LPAREN arguments RPAREN");
|
// exprargs -> LPAREN arguments RPAREN
|
||||||
check(Token.Symbol.LPAREN);
|
check(Token.Symbol.LPAREN);
|
||||||
parseArguments();
|
List<AST.Expr> args = parseArguments();
|
||||||
check(Token.Symbol.RPAREN);
|
check(Token.Symbol.RPAREN);
|
||||||
} else {
|
return args;
|
||||||
System.out.println("exprargs -> ε");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseArguments() {
|
// exprargs -> ε
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AST.Expr> parseArguments() {
|
||||||
|
List<AST.Expr> args = new ArrayList<>();
|
||||||
|
|
||||||
Token token = lexAn.peekToken();
|
Token token = lexAn.peekToken();
|
||||||
if (token.symbol() == Token.Symbol.RPAREN) {
|
if (token.symbol() == Token.Symbol.RPAREN) {
|
||||||
System.out.println("arguments -> ε");
|
// arguments -> ε
|
||||||
} else {
|
return args;
|
||||||
System.out.println("arguments -> expression restargs");
|
|
||||||
parseExpression();
|
|
||||||
parseRestArguments();
|
|
||||||
}
|
}
|
||||||
|
// arguments -> expression restargs
|
||||||
|
args.add(parseExpression());
|
||||||
|
parseRestArguments(args);
|
||||||
|
|
||||||
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseRestArguments() {
|
private void parseRestArguments(List<AST.Expr> args) {
|
||||||
if (lexAn.peekToken().symbol() == Token.Symbol.COMMA) {
|
if (lexAn.peekToken().symbol() == Token.Symbol.COMMA) {
|
||||||
System.out.println("restargs -> COMMA restargs");
|
// restargs -> COMMA restargs
|
||||||
check(Token.Symbol.COMMA);
|
check(Token.Symbol.COMMA);
|
||||||
parseExpression();
|
args.add(parseExpression());
|
||||||
parseRestArguments();
|
parseRestArguments(args);
|
||||||
} else {
|
|
||||||
System.out.println("restargs -> ε");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,7 +767,7 @@ public class SynAn implements AutoCloseable {
|
|||||||
Report.warning("Unused arguments in the command line.");
|
Report.warning("Unused arguments in the command line.");
|
||||||
|
|
||||||
try (SynAn synAn = new SynAn(cmdLineArgs[0])) {
|
try (SynAn synAn = new SynAn(cmdLineArgs[0])) {
|
||||||
synAn.parse();
|
synAn.parse(new HashMap<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upajmo, da kdaj pridemo to te tocke.
|
// Upajmo, da kdaj pridemo to te tocke.
|
||||||
|
1
zip.sh
1
zip.sh
@ -7,5 +7,6 @@ mkdir pins25
|
|||||||
rsync -av --exclude=".*" ./src ./pins25
|
rsync -av --exclude=".*" ./src ./pins25
|
||||||
rsync -av --exclude=".*" --exclude="*.pins" ./prg ./pins25
|
rsync -av --exclude=".*" --exclude="*.pins" ./prg ./pins25
|
||||||
rm ./pins25/prg/*.pins
|
rm ./pins25/prg/*.pins
|
||||||
|
rm 63230048-"$phase".zip
|
||||||
zip -r 63230048-"$phase".zip ./pins25
|
zip -r 63230048-"$phase".zip ./pins25
|
||||||
rm -rf ./pins25
|
rm -rf ./pins25
|
||||||
|
Loading…
x
Reference in New Issue
Block a user