Begin cleanup of array parsing
TODO: debug segfault
This commit is contained in:
parent
985f02723e
commit
999f8dc267
|
@ -257,6 +257,7 @@ int ParseOptionalPointer();
|
||||||
int ValueAt(int Type);
|
int ValueAt(int Type);
|
||||||
int PointerTo(int Type);
|
int PointerTo(int Type);
|
||||||
|
|
||||||
|
struct ASTNode* AccessArray();
|
||||||
|
|
||||||
int ParseTokenToOperation(int Token);
|
int ParseTokenToOperation(int Token);
|
||||||
|
|
||||||
|
|
12
src/Main.c
12
src/Main.c
|
@ -15,6 +15,7 @@ int TypeSizes[9] = { 0, 1, 4, 8, 0, 8, 8,
|
||||||
char* TokenStrings[] = { "+", "-", "*", "/", "int" };
|
char* TokenStrings[] = { "+", "-", "*", "/", "int" };
|
||||||
char* TokenNames[] = {
|
char* TokenNames[] = {
|
||||||
"End of file",
|
"End of file",
|
||||||
|
"Equivalency",
|
||||||
|
|
||||||
"Addition",
|
"Addition",
|
||||||
"Subtraction",
|
"Subtraction",
|
||||||
|
@ -28,17 +29,20 @@ char* TokenNames[] = {
|
||||||
"Less Than or Equal",
|
"Less Than or Equal",
|
||||||
"Greater Than or Equal",
|
"Greater Than or Equal",
|
||||||
|
|
||||||
"Assignment",
|
|
||||||
"Integer literal",
|
"Integer literal",
|
||||||
"Statement End",
|
"Statement End",
|
||||||
|
|
||||||
"Compound Block Start",
|
"Compound Block Start",
|
||||||
"Compound Block End",
|
"Compound Block End",
|
||||||
|
|
||||||
|
"Array index start",
|
||||||
|
"Array index end",
|
||||||
|
|
||||||
"Logical Block Start",
|
"Logical Block Start",
|
||||||
"Logical Block End",
|
"Logical Block End",
|
||||||
|
|
||||||
"Dereference operator",
|
"Dereference operator",
|
||||||
|
"Comma",
|
||||||
|
|
||||||
"Identifier",
|
"Identifier",
|
||||||
"None Type",
|
"None Type",
|
||||||
|
@ -103,16 +107,16 @@ void Die(char* Error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DieMessage(char* Error, char* Reason) {
|
void DieMessage(char* Error, char* Reason) {
|
||||||
fprintf(stderr, "%s:%s on line %d\n", Error, Reason, Line);
|
fprintf(stderr, "%s: %s on line %d\n", Error, Reason, Line);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DieDecimal(char* Error, int Number) {
|
void DieDecimal(char* Error, int Number) {
|
||||||
fprintf(stderr, "%s:%d on line %d\n", Error, Number, Line);
|
fprintf(stderr, "%s: %d on line %d\n", Error, Number, Line);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DieChar(char* Error, int Char) {
|
void DieChar(char* Error, int Char) {
|
||||||
fprintf(stderr, "%s:%c on line %d\n", Error, Char, Line);
|
fprintf(stderr, "%s: %c on line %d\n", Error, Char, Line);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
36
src/Parser.c
36
src/Parser.c
|
@ -28,8 +28,8 @@ static int Precedence[] =
|
||||||
static int OperatorPrecedence(int Token) {
|
static int OperatorPrecedence(int Token) {
|
||||||
int Prec = Precedence[Token];
|
int Prec = Precedence[Token];
|
||||||
|
|
||||||
if(Prec == 0) {
|
if(Prec == 0 || Token >= RET_VOID) {
|
||||||
Die("Attempting to determine operator precedence of an EOF or INT literal.");
|
DieMessage("Attempting to determine operator precedence of an EOF or INT literal", TokenNames[Token]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Prec;
|
return Prec;
|
||||||
|
@ -114,8 +114,6 @@ struct ASTNode* ParsePrimary(void) {
|
||||||
Node = ConstructASTLeaf(TERM_INTLITERAL, RET_CHAR, CurrentToken.value);
|
Node = ConstructASTLeaf(TERM_INTLITERAL, RET_CHAR, CurrentToken.value);
|
||||||
else
|
else
|
||||||
Node = ConstructASTLeaf(TERM_INTLITERAL, RET_INT, CurrentToken.value);
|
Node = ConstructASTLeaf(TERM_INTLITERAL, RET_INT, CurrentToken.value);
|
||||||
|
|
||||||
//Tokenise(&CurrentToken); // Fetch next token
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TY_IDENTIFIER:
|
case TY_IDENTIFIER:
|
||||||
|
@ -128,9 +126,11 @@ struct ASTNode* ParsePrimary(void) {
|
||||||
if(CurrentToken.type == LI_LPARE)
|
if(CurrentToken.type == LI_LPARE)
|
||||||
return CallFunction();
|
return CallFunction();
|
||||||
|
|
||||||
|
if(CurrentToken.type == LI_LBRAS)
|
||||||
|
return AccessArray();
|
||||||
|
|
||||||
// Otherwise, we've read too far and need to go back.
|
// Otherwise, we've read too far and need to go back.
|
||||||
RejectToken(&CurrentToken);
|
RejectToken(&CurrentToken);
|
||||||
|
|
||||||
// It's a variable, so find the symbol and construct a leaf for it
|
// It's a variable, so find the symbol and construct a leaf for it
|
||||||
ID = FindSymbol(CurrentIdentifier);
|
ID = FindSymbol(CurrentIdentifier);
|
||||||
if(ID == -1)
|
if(ID == -1)
|
||||||
|
@ -138,24 +138,18 @@ struct ASTNode* ParsePrimary(void) {
|
||||||
Node = ConstructASTLeaf(REF_IDENT, Symbols[ID].Type, ID);
|
Node = ConstructASTLeaf(REF_IDENT, Symbols[ID].Type, ID);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LI_LPARE:
|
case LI_RPARE:
|
||||||
// We're expecting a primary encased in parentheses.
|
// Starting a ( expr ) block
|
||||||
// That means, we tokenise the next item
|
|
||||||
Tokenise(&CurrentToken);
|
Tokenise(&CurrentToken);
|
||||||
// Then, we expect a valid expression
|
|
||||||
Node = ParsePrecedenceASTNode(0);
|
Node = ParsePrecedenceASTNode(0);
|
||||||
|
|
||||||
// Then, after the expression is parsed, we're returned here.
|
// Make sure we close
|
||||||
// since the expression is ENCASED in parens, we expect another.
|
|
||||||
VerifyToken(LI_RPARE, ")");
|
VerifyToken(LI_RPARE, ")");
|
||||||
|
|
||||||
// Skip the next tokenise and return early
|
|
||||||
return Node;
|
return Node;
|
||||||
|
|
||||||
default:
|
|
||||||
DieDecimal("Unable to parse primary type", CurrentToken.type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Tokenise(&CurrentToken);
|
Tokenise(&CurrentToken);
|
||||||
|
|
||||||
return Node;
|
return Node;
|
||||||
|
@ -171,11 +165,13 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
|
||||||
LeftNode = PrefixStatement();
|
LeftNode = PrefixStatement();
|
||||||
|
|
||||||
NodeType = CurrentToken.type;
|
NodeType = CurrentToken.type;
|
||||||
if(NodeType == LI_SEMIC || NodeType == LI_RPARE) {
|
printf("%d\r\n", CurrentToken.type);
|
||||||
|
if(NodeType == LI_SEMIC || NodeType == LI_RPARE || NodeType == LI_RBRAS) {
|
||||||
|
printf("Current token matches ; ) ]\r\n");
|
||||||
LeftNode->RVal = 1; return LeftNode;
|
LeftNode->RVal = 1; return LeftNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Current token has value %d, type %d\n", CurrentToken.value, CurrentToken.type);
|
printf("Current token has value %d, type %s\n", CurrentToken.value, TokenNames[CurrentToken.type]);
|
||||||
while((OperatorPrecedence(NodeType) > PreviousTokenPrecedence) || (IsRightExpr(OpType) && OperatorPrecedence(OpType) == PreviousTokenPrecedence)) {
|
while((OperatorPrecedence(NodeType) > PreviousTokenPrecedence) || (IsRightExpr(OpType) && OperatorPrecedence(OpType) == PreviousTokenPrecedence)) {
|
||||||
//printf("inside while\n");
|
//printf("inside while\n");
|
||||||
Tokenise(&CurrentToken);
|
Tokenise(&CurrentToken);
|
||||||
|
@ -254,7 +250,7 @@ struct ASTNode* ParsePrecedenceASTNode(int PreviousTokenPrecedence) {
|
||||||
*/
|
*/
|
||||||
LeftNode = ConstructASTNode(ParseTokenToOperation(NodeType), LeftNode->ExprType, LeftNode, NULL, RightNode, 0);
|
LeftNode = ConstructASTNode(ParseTokenToOperation(NodeType), LeftNode->ExprType, LeftNode, NULL, RightNode, 0);
|
||||||
NodeType = CurrentToken.type;
|
NodeType = CurrentToken.type;
|
||||||
if(NodeType == LI_SEMIC || NodeType == LI_RPARE) {
|
if(NodeType == LI_SEMIC || NodeType == LI_RPARE || NodeType == LI_RBRAS) {
|
||||||
LeftNode->RVal = 1;
|
LeftNode->RVal = 1;
|
||||||
return LeftNode;
|
return LeftNode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,3 +65,30 @@ int ParseOptionalPointer() {
|
||||||
return Type;
|
return Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ASTNode* AccessArray() {
|
||||||
|
struct ASTNode* LeftNode, *RightNode;
|
||||||
|
int ID;
|
||||||
|
|
||||||
|
printf("\tAccessing array %s as requested\r\n", CurrentIdentifier);
|
||||||
|
if ((ID = FindSymbol(CurrentIdentifier)) == -1 || Symbols[ID].Structure != ST_ARR)
|
||||||
|
DieMessage("Accessing undeclared array", CurrentIdentifier);
|
||||||
|
|
||||||
|
LeftNode = ConstructASTLeaf(OP_ADDRESS, Symbols[ID].Type, ID);
|
||||||
|
printf("\t\tCurrent token: %s\r\n", TokenNames[CurrentToken.type]);
|
||||||
|
Tokenise(&CurrentToken);
|
||||||
|
printf("\t\tCurrent token: %s\r\n", TokenNames[CurrentToken.type]);
|
||||||
|
|
||||||
|
RightNode = ParsePrecedenceASTNode(0);
|
||||||
|
|
||||||
|
VerifyToken(LI_RBRAS, "]");
|
||||||
|
|
||||||
|
if(!TypeIsInt(RightNode->ExprType))
|
||||||
|
Die("Array index is not integer");
|
||||||
|
|
||||||
|
RightNode = MutateType(RightNode, LeftNode->ExprType, OP_ADD);
|
||||||
|
|
||||||
|
LeftNode = ConstructASTNode(OP_ADD, Symbols[ID].Type, LeftNode, NULL, RightNode, 0);
|
||||||
|
LeftNode = ConstructASTBranch(OP_DEREF, ValueAt(LeftNode->ExprType), LeftNode, 0);
|
||||||
|
|
||||||
|
return LeftNode;
|
||||||
|
}
|
10
tests/arrays1
Normal file
10
tests/arrays1
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
int a;
|
||||||
|
int b[25];
|
||||||
|
|
||||||
|
int :: main() {
|
||||||
|
b[3] = 12;
|
||||||
|
a = b[3];
|
||||||
|
PrintInteger(a);
|
||||||
|
PrintInteger(b[5]);
|
||||||
|
return(0);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user