Fixed parsing bug 1, just empty FactorSequence left

This commit is contained in:
RochesterX
2026-01-31 19:51:05 -05:00
parent 2e3dd13009
commit 1d9ad824a6
10 changed files with 145 additions and 59 deletions

View File

@@ -348,29 +348,6 @@ func lex(string: String) -> [Substring] {
return []
}
func parse(lexed: [Substring]) -> String {
var tokens: [Token] = [Token]()
for token: Substring in lexed {
let tokenType: TokenType = categorizeToken(token: token)
tokens.append(Token(content: token, type: tokenType))
}
tokens = tokens.reversed()
let abstractSyntaxTree = SyntaxTreeNode(.Root)
if validateConstruct(program.variants[.SingleFunction]!, tokens: &tokens, node: abstractSyntaxTree) != .Invalid {
print("Success")
print(abstractSyntaxTree.text())
print("Assembly:")
let assembly: String = generateOutput(abstractSyntaxTree)
print(assembly)
return assembly
}
print("Distinct lack of success")
return ""
}
func generateOutput(_ node: SyntaxTreeNode) -> String {
var text: String = ""
switch node.variant {
@@ -387,10 +364,48 @@ func generateOutput(_ node: SyntaxTreeNode) -> String {
break
case .FactorSequence:
for child in node.children {
var operation: ConstructVariant = .Error
let count = node.children.count
if count == 0 {
print("ERROR: FactorSequence with no children")
break
}
for i in 0...count - 1 {
let child: SyntaxTreeNode = node.children[i]
// Operation
if i % 2 == 1 {
operation = child.variant
continue
}
text += generateOutput(child)
switch operation {
case .Multiplication:
text += " pop %ecx\n"
text += " imul %ecx, %eax\n"
default:
if i != 0 {
print("Unknown operation \"\(operation)\" in FactorSequence")
}
break
}
if i != node.children.count - 1 {
text += " push %eax\n"
}
}
break
/*
<CODE FOR e1 GOES HERE>
push %eax ; save value of e1 on the stack
<CODE FOR e2 GOES HERE>
pop %ecx ; pop e1 from the stack into ecx
addl %ecx, %eax ; add e1 to e2, save results in eax
*/
case .Integer:
text += " .globl \(node.value)\n\(node.value):\n"
@@ -444,13 +459,36 @@ func generateOutput(_ node: SyntaxTreeNode) -> String {
return text
}
func parse(lexed: [Substring]) -> String {
var tokens: [Token] = [Token]()
for token: Substring in lexed {
let tokenType: TokenType = categorizeToken(token: token)
tokens.append(Token(content: token, type: tokenType))
}
tokens = tokens.reversed()
let abstractSyntaxTree = SyntaxTreeNode(.Root)
if validateConstruct(program.variants[.SingleFunction]!, tokens: &tokens, node: abstractSyntaxTree, loopingEnabled: false) != .Invalid {
print("Success")
print(abstractSyntaxTree.text())
print("Assembly:")
let assembly: String = generateOutput(abstractSyntaxTree)
print(assembly)
return assembly
}
print("Distinct lack of success")
return ""
}
enum Validity {
case Valid
case Invalid
case Break
}
func validateConstruct(_ construct: Construct, tokens: inout [Token], node: SyntaxTreeNode) -> Validity {
func validateConstruct(_ construct: Construct, tokens: inout [Token], node: SyntaxTreeNode, loopingEnabled: Bool) -> Validity {
var indent: String {
var count: Int = 0
var child: SyntaxTreeNode = node
@@ -461,7 +499,7 @@ func validateConstruct(_ construct: Construct, tokens: inout [Token], node: Synt
return String(repeating: " ", count: count)
}
var loop: Bool = false
var loop: Bool = loopingEnabled
repeat {
for element in construct {
switch element {
@@ -471,18 +509,23 @@ func validateConstruct(_ construct: Construct, tokens: inout [Token], node: Synt
var valid: Validity = .Invalid
var validVariant: ConstructVariant = .Error
let tokenBackup: [Token] = tokens
for key in constructDefinitions[type]!.keys {
let childNode = node.addChild(value: key)
print("\(indent)Testing variant \(key) (Loop = \(loop))")
valid = validateConstruct(constructDefinitions[type]![key]!, tokens: &tokens, node: childNode)
for variant in constructDefinitions[type]!.keys {
let childNode = node.addChild(value: variant)
var loopable = false
if variant == .FactorSequence || variant == .TermSequence {
loopable = true
}
print("\(indent)Testing variant \(variant) (Loop = \(loop)) (Loopable = \(loopable))")
valid = validateConstruct(constructDefinitions[type]![variant]!, tokens: &tokens, node: childNode, loopingEnabled: loopable)
if valid == .Invalid {
print("\(indent)Fail")
print("\(indent)Fail (no valid variants)\n")
tokens = tokenBackup
_ = node.popLastChild()
continue
}
print("\(indent)Success")
validVariant = key
print("\(indent)Success (variant \"\(variant)\")\n")
validVariant = variant
break
}
@@ -490,6 +533,7 @@ func validateConstruct(_ construct: Construct, tokens: inout [Token], node: Synt
if loopingEnabled {
// Factor looping nonsense
if type == .Factor {
let nextToken: Token = tokens[tokens.count - 1]
@@ -515,6 +559,7 @@ func validateConstruct(_ construct: Construct, tokens: inout [Token], node: Synt
return .Break
}
}
}

BIN
a.out

Binary file not shown.

3
hard.c Normal file
View File

@@ -0,0 +1,3 @@
int main() {
return !(2 * 3) + !2 * 3 + (4 + 5) * ~6 * 7 * (8 + -(!~9 * 10)) - -11 * ~12 + !~-13;
}

24
hard.s Normal file
View File

@@ -0,0 +1,24 @@
.globl main
main:
cmpl $0, %eax
movl $0, %eax
sete %al
movl $2, %eax
cmpl $0, %eax
movl $0, %eax
sete %al
movl $3, %eax
movl $6, %eax
not %eax
movl $7, %eax
movl $11, %eax
neg %eax
movl $12, %eax
not %eax
movl $13, %eax
neg %eax
not %eax
cmpl $0, %eax
movl $0, %eax
sete %al
ret

4
test
View File

@@ -1,6 +1,6 @@
#!/bin/bash
gcc c/tests/stage_2/valid/$1.c
gcc bin/$1.s -o my.out
gcc $1.c
gcc $1.s -o my.out
echo "GCC:"
./a.out
echo $?

2
test.c
View File

@@ -1,3 +1,3 @@
int main() {
return !1 * 1;
return 1 * 2;
}

8
test.s
View File

@@ -0,0 +1,8 @@
.globl main
main:
movl $1, %eax
push %eax
movl $2, %eax
pop %ecx
imul %ecx, %eax
ret

View File

@@ -1,3 +1,3 @@
int main() {
return (~2 + !(4 - 2) / 9 - -9) + 90 * 8 - 2 - 33 * (400 - 1) - !~-9;
return ~1 * 2;
}

View File

@@ -0,0 +1,6 @@
.globl main
main:
movl $1, %eax
not %eax
movl $2, %eax
ret

0
test2s Normal file
View File