run.mjs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import { readFileSync } from 'node:fs'
  2. import { logTree } from './print-tree.mjs'
  3. import { parser as LaTeXParser } from '../../frontend/js/features/source-editor/lezer-latex/latex.mjs'
  4. import { parser as BibTeXParser } from '../../frontend/js/features/source-editor/lezer-bibtex/bibtex.mjs'
  5. // Runs the lezer-latex or lezer-bibtex parser on a supplied file, and prints the resulting
  6. // parse tree to stdout
  7. //
  8. // show parse tree: lezer-latex-run.js test/unit/src/LezerLatex/examples/amsmath.tex
  9. // lezer-latex-run.js test/unit/src/LezerLatex/examples/overleaf.bib
  10. // show error summary: lezer-latex-run.js coverage test/unit/src/LezerLatex/examples/amsmath.tex
  11. let files = process.argv.slice(2)
  12. if (!files.length) {
  13. files = ['test/unit/src/LezerLatex/examples/demo.tex']
  14. }
  15. let coverage = false
  16. if (files[0] === 'coverage') {
  17. // count errors
  18. coverage = true
  19. files.shift()
  20. }
  21. function reportErrorCounts(output) {
  22. if (coverage) process.stdout.write(output)
  23. }
  24. function parseFile(filename) {
  25. const text = readFileSync(filename).toString()
  26. const t0 = process.hrtime()
  27. const parser = filename.endsWith('.bib') ? BibTeXParser : LaTeXParser
  28. const tree = parser.parse(text)
  29. const dt = process.hrtime(t0)
  30. const timeTaken = dt[0] + dt[1] * 1e-9
  31. let errorCount = 0
  32. let nodeCount = 0
  33. tree.iterate({
  34. enter: syntaxNodeRef => {
  35. nodeCount++
  36. if (syntaxNodeRef.type.isError) {
  37. errorCount++
  38. }
  39. },
  40. })
  41. if (!coverage) logTree(tree, text)
  42. return { nodeCount, errorCount, timeTaken, bytes: text.length }
  43. }
  44. let totalErrors = 0
  45. let totalTime = 0
  46. let totalBytes = 0
  47. for (const file of files) {
  48. const { nodeCount, errorCount, timeTaken, bytes } = parseFile(file)
  49. const errorRate = Math.round((100 * errorCount) / nodeCount)
  50. totalErrors += errorCount
  51. totalTime += timeTaken
  52. totalBytes += bytes
  53. reportErrorCounts(
  54. `${errorCount} errors`.padStart(12) +
  55. `${nodeCount} nodes`.padStart(12) +
  56. `(${errorRate}%)`.padStart(6) +
  57. `${(1000 * timeTaken).toFixed(1)} ms`.padStart(8) +
  58. `${(bytes / 1024).toFixed(1)} KB`.padStart(8) +
  59. ` ${file}\n`
  60. )
  61. }
  62. const timeInMilliseconds = 1000 * totalTime
  63. const hundredKBs = totalBytes / (100 * 1024)
  64. reportErrorCounts(
  65. `\ntotal errors ${totalErrors}, performance ${(
  66. timeInMilliseconds / hundredKBs
  67. ).toFixed(1)} ms/100KB \n`
  68. )
  69. if (totalErrors > 0) {
  70. process.exit(1) // return non-zero exit status for tests
  71. }