Parser: corpus parse rate 69% -> 81%, and stop --tests from sticking
Grammar: 'using,except(x)' modifiers, '#ifx' with block branches, unions with
parameters, multi-value initializers, mixed 'name:, lvalue = call()' targets,
'push_context' with no explicit context, 'operator []=', '#foreign lib "symbol"',
keyword-named arguments such as 'remove={...}', and '#insert (options) body'.
Directive flags now require adjacency: without it, in
'(callback: (*GUID) #c_call, lpContext: *void)' the flag swallowed ', lpContext'.
procModifier is now just directiveExpr — one rule for directives in both
positions, so fixes apply everywhere.
jaitest: a '--tests' filter persisted through Gradle's configuration cache, so a
later unfiltered ./jaitest silently re-ran only that class and printed OK.
Unfiltered runs now disable the configuration cache.
MIN_CLEAN_FILES ratchets the corpus gate at 575/714.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package dev.hgh.jai.parser
|
||||
|
||||
import com.intellij.psi.PsiErrorElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiFileFactory
|
||||
import com.intellij.psi.PsiRecursiveElementWalkingVisitor
|
||||
import com.intellij.testFramework.fixtures.BasePlatformTestCase
|
||||
@@ -9,39 +10,30 @@ import java.io.File
|
||||
|
||||
/**
|
||||
* Scratch harness for grammar work. Not a gate — the gate is [JaiCorpusParserTest].
|
||||
*
|
||||
* Set `-Djai.debug.file=<path>` to dump every error in one corpus file instead.
|
||||
* Edit [snippets] and [corpusFiles] freely while iterating on `Jai.bnf`.
|
||||
*/
|
||||
class DebugParseTest : BasePlatformTestCase() {
|
||||
private val snippets =
|
||||
listOf(
|
||||
"tzname: **u8 #elsewhere libc;\n",
|
||||
"S :: struct {\n #as unknown: IUnknown;\n}\n",
|
||||
"x.magic = (.*) cast(*u32) DATA.data;\n",
|
||||
"M :: #library,system,link_always \"Metal\";\n",
|
||||
"f :: (s: *u8, \$strict := false) -> u32 { return 1; }\n",
|
||||
"#module_parameters (MAX := 4, VERBOSE := false);\n",
|
||||
"Allocator_Proc :: #type (mode: int, old: *void) -> *void;\n",
|
||||
"SimpleProcedure :: #type () -> ();\n",
|
||||
"n := tprint(\"%\", ifx options.output_path else \".\");\n",
|
||||
"v :: (info: *File_Visit_Info, modules : *[..] string) { }\n",
|
||||
"B :: struct (type: Type, by_pointer := false) { }\n",
|
||||
"e := ifx a then b;\n",
|
||||
"#scope_file\n\n\nbig_endian :: () -> bool {\n return true;\n}\n",
|
||||
"S :: struct {\n #as using,except(vtable) iunknown: IUnknown;\n}\n",
|
||||
"using,except(FT_Init) new_module :: #import \"freetype\";\n",
|
||||
"operator []= :: inline (a: *B, i: int, v: bool) { }\n",
|
||||
"inotify_init :: (flags: s32 = 0) -> s32 #foreign libc \"inotify_init1\";\n",
|
||||
"F :: (a: *L) -> E #foreign ft #deprecated \"msg\";\n",
|
||||
)
|
||||
|
||||
/** Corpus files to dump the first error of; edit freely while working. */
|
||||
/** Corpus files to dump the first error of. */
|
||||
private val corpusFiles =
|
||||
listOf(
|
||||
"modules/Sound_Player/os/win32.jai",
|
||||
"examples/module_info.jai",
|
||||
"how_to/800_allocators.jai",
|
||||
"modules/POSIX/module.jai",
|
||||
"modules/Basic/module.jai",
|
||||
"modules/Compiler/module.jai",
|
||||
"modules/Window_Creation/module.jai",
|
||||
"modules/String/module.jai",
|
||||
"modules/Hash_Table.jai",
|
||||
"modules/Math/module.jai",
|
||||
"modules/Basic/Array.jai",
|
||||
"modules/Debug/windows.jai",
|
||||
"modules/Simp/backend/gl.jai",
|
||||
"modules/GetRect/system/occlusion.jai",
|
||||
"modules/POSIX/compare_bindings.jai",
|
||||
"modules/Android/Toolchain/apk.jai",
|
||||
"modules/Curl/examples/ftp.jai",
|
||||
"modules/Objective_C/LightweightRenderingView/module.jai",
|
||||
)
|
||||
|
||||
fun testCorpusFiles() {
|
||||
@@ -54,11 +46,6 @@ class DebugParseTest : BasePlatformTestCase() {
|
||||
}
|
||||
|
||||
fun testSnippets() {
|
||||
val debugFile = System.getProperty("jai.debug.file")
|
||||
if (debugFile != null) {
|
||||
dumpFile(File(debugFile))
|
||||
return
|
||||
}
|
||||
val factory = PsiFileFactory.getInstance(project)
|
||||
var failures = 0
|
||||
for (text in snippets) {
|
||||
@@ -89,7 +76,7 @@ class DebugParseTest : BasePlatformTestCase() {
|
||||
println(" at '${text.substring(error.textOffset).take(80).replace("\n", "\\n")}'")
|
||||
}
|
||||
|
||||
private fun firstError(file: com.intellij.psi.PsiFile): PsiErrorElement? {
|
||||
private fun firstError(file: PsiFile): PsiErrorElement? {
|
||||
var first: PsiErrorElement? = null
|
||||
file.accept(
|
||||
object : PsiRecursiveElementWalkingVisitor() {
|
||||
|
||||
@@ -36,6 +36,7 @@ class JaiCorpusParserTest : BasePlatformTestCase() {
|
||||
var totalErrors = 0
|
||||
val filesWithErrors = mutableListOf<String>()
|
||||
val firstErrors = mutableListOf<String>()
|
||||
val allErrors = mutableListOf<String>()
|
||||
val histogram = mutableMapOf<String, Int>()
|
||||
|
||||
for (file in jaiFiles) {
|
||||
@@ -62,10 +63,8 @@ class JaiCorpusParserTest : BasePlatformTestCase() {
|
||||
val offset = error.textOffset
|
||||
val got = snippet(text, offset).take(GOT_WIDTH)
|
||||
histogram.merge(got, 1, Int::plus)
|
||||
if (firstErrors.size < REPORTED_ERRORS) {
|
||||
val line = text.substring(0, offset).count { it == '\n' } + 1
|
||||
firstErrors.add("$relative:$line: ${error.errorDescription} [at '$got']")
|
||||
}
|
||||
val line = text.substring(0, offset).count { it == '\n' } + 1
|
||||
allErrors.add("$relative:$line: ${error.errorDescription} [at '$got']")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +81,10 @@ class JaiCorpusParserTest : BasePlatformTestCase() {
|
||||
.take(REPORTED_KINDS)
|
||||
.forEach { (token, count) -> println(" %5d %s".format(count, token)) }
|
||||
}
|
||||
// A spread across the corpus, not the first N alphabetically: the failures
|
||||
// cluster by directory, so an alphabetical head hides whole categories.
|
||||
val stride = maxOf(1, allErrors.size / REPORTED_ERRORS)
|
||||
allErrors.filterIndexed { index, _ -> index % stride == 0 }.take(REPORTED_ERRORS).forEach { println(" $it") }
|
||||
firstErrors.forEach { println(" $it") }
|
||||
|
||||
assertTrue(
|
||||
@@ -103,7 +106,7 @@ class JaiCorpusParserTest : BasePlatformTestCase() {
|
||||
|
||||
private companion object {
|
||||
/** Ratchet. Raise it as the grammar improves; never lower it. */
|
||||
const val MIN_CLEAN_FILES = 4
|
||||
const val MIN_CLEAN_FILES = 575
|
||||
const val REPORTED_ERRORS = 25
|
||||
const val REPORTED_KINDS = 20
|
||||
const val GOT_WIDTH = 14
|
||||
|
||||
Reference in New Issue
Block a user