Fixed parsing bug 1, just empty FactorSequence left
This commit is contained in:
@@ -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,13 +364,51 @@ 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"
|
||||
text += " .globl \(node.value)\n\(node.value):\n"
|
||||
for child in node.children {
|
||||
text += generateOutput(child)
|
||||
}
|
||||
@@ -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,29 +533,31 @@ func validateConstruct(_ construct: Construct, tokens: inout [Token], node: Synt
|
||||
|
||||
|
||||
|
||||
// Factor looping nonsense
|
||||
if type == .Factor {
|
||||
let nextToken: Token = tokens[tokens.count - 1]
|
||||
if nextToken.type == .MULTIPLICATION || nextToken.type == .DIVISION {
|
||||
print("\(indent)Looping due to factor")
|
||||
loop = true
|
||||
} else {
|
||||
print("\(indent)Breaking out of factor loop")
|
||||
loop = false
|
||||
return .Break
|
||||
if loopingEnabled {
|
||||
// Factor looping nonsense
|
||||
if type == .Factor {
|
||||
let nextToken: Token = tokens[tokens.count - 1]
|
||||
if nextToken.type == .MULTIPLICATION || nextToken.type == .DIVISION {
|
||||
print("\(indent)Looping due to factor")
|
||||
loop = true
|
||||
} else {
|
||||
print("\(indent)Breaking out of factor loop")
|
||||
loop = false
|
||||
return .Break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Term looping nonsense
|
||||
else if type == .Term {
|
||||
let nextToken: Token = tokens[tokens.count - 1]
|
||||
if nextToken.type == .ADDITION || nextToken.type == .NEGATION {
|
||||
print("\(indent)Looping due to term")
|
||||
loop = true
|
||||
} else {
|
||||
print("\(indent)Breaking out of term loop")
|
||||
loop = false
|
||||
return .Break
|
||||
// Term looping nonsense
|
||||
else if type == .Term {
|
||||
let nextToken: Token = tokens[tokens.count - 1]
|
||||
if nextToken.type == .ADDITION || nextToken.type == .NEGATION {
|
||||
print("\(indent)Looping due to term")
|
||||
loop = true
|
||||
} else {
|
||||
print("\(indent)Breaking out of term loop")
|
||||
loop = false
|
||||
return .Break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
3
hard.c
Normal file
3
hard.c
Normal 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
24
hard.s
Normal 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
4
test
@@ -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 $?
|
||||
|
||||
8
test.s
8
test.s
@@ -0,0 +1,8 @@
|
||||
.globl main
|
||||
main:
|
||||
movl $1, %eax
|
||||
push %eax
|
||||
movl $2, %eax
|
||||
pop %ecx
|
||||
imul %ecx, %eax
|
||||
ret
|
||||
|
||||
2
test2.c
2
test2.c
@@ -1,3 +1,3 @@
|
||||
int main() {
|
||||
return (~2 + !(4 - 2) / 9 - -9) + 90 * 8 - 2 - 33 * (400 - 1) - !~-9;
|
||||
return ~1 * 2;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user