-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathParser.java
More file actions
117 lines (101 loc) · 3.22 KB
/
Parser.java
File metadata and controls
117 lines (101 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import java.util.List;
public class Parser {
private final List<Token> tokens;
private int current = 0;
public Parser(List<Token> tokens) {
this.tokens = tokens;
}
public Sentence Parse() {
Sentence sentence = Sentence();
if (sentence == null) {
Main.reportError(1, "Parser", "Sentence not valid.");
}
return sentence;
}
// <Sentence> -> <AtomicSentence> | <ComplexSentence>
private Sentence Sentence() {
Sentence sentence = ComplexSentence();
return sentence != null ? sentence : AtomicSentence();
}
private Sentence ComplexSentence() {
if (match(TokenType.LEFT_PAREN)) {
// "(" <Sentence> ")"
Sentence sentence = Sentence();
if (sentence == null) {
if(peek().getType() == TokenType.RIGHT_PAREN) {
Main.reportError(1, "Parser", "Sentence expected inside parenthesis.");
} else {
Main.reportError(1, "Parser", "Incomplete Binary Operation: " + peek().getLexeme());
}
}
if (!match(TokenType.RIGHT_PAREN)) {
Main.reportError(1, "Parser", "Invalid Sentence.");
}
if (Connective()) {
Token operator = previous();
if (operator.getType() == TokenType.NOT) {
Main.reportError(1, "Parser", "NOT cannot be used a connective.");
}
Sentence right = Sentence();
if (right == null) {
Main.reportError(1, "Parser", "Incomplete Binary Operation: " + previous().getLexeme());
}
return new Sentence.Binary(sentence, operator, right);
}
return new Sentence.Grouping(sentence);
}
if (match(TokenType.NOT)) {
// "NOT" <Sentence>
Token operator = previous();
Sentence right = Sentence();
if (right == null) {
Main.reportError(1, "Parser", "Expected sentence after NOT.");
}
return new Sentence.Unary(operator, right);
}
return null;
}
// <AtomicSentence> -> "TRUE" | "FALSE" | "P" | "Q" | "S"
private Sentence AtomicSentence() {
if (match(TokenType.TRUE, TokenType.FALSE, TokenType.IDENTIFIERS)) {
Token token = previous();
return new Sentence.AtomicSentence(token.getLexeme());
}
return null;
}
// <Connective> -> "AND" | "OR" | "IMPLIES" | "EQUIVALENT"
private boolean Connective() {
return match(TokenType.AND) || match(TokenType.OR) || match(TokenType.IMPLIES) || match(TokenType.EQUIVALENT) || match(TokenType.NOT);
}
// Check if the current token matches any of the given types
private boolean match(TokenType... types) {
for (TokenType type : types) {
if (check(type)) {
advance();
return true;
}
}
return false;
}
// Check if the current token matches the given type
private boolean check(TokenType type) {
return !isAtEnd() && peek().getType() == type;
}
// Consume and return the current token
private Token advance() {
if (!isAtEnd()) current++;
return previous();
}
// Return true if at the end of the token list
private boolean isAtEnd() {
return peek().getType() == TokenType.EOF;
}
// Get the current token
private Token peek() {
return tokens.get(current);
}
// Get the previous token
private Token previous() {
return tokens.get(current - 1);
}
}