struct-parser.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. const {
  2. createAliasMap,
  3. findStruct,
  4. findStructs,
  5. normalizeLookupName,
  6. normalizeTypeText,
  7. parseDeclarator,
  8. splitDeclarators,
  9. stripComments
  10. } = require('./struct-c-syntax.js')
  11. const {
  12. parseStructFields
  13. } = require('./struct-layout.js')
  14. const STRUCT_VARIABLE_QUALIFIERS = {
  15. code: true,
  16. const: true,
  17. data: true,
  18. extern: true,
  19. idata: true,
  20. pdata: true,
  21. static: true,
  22. volatile: true,
  23. xdata: true
  24. }
  25. function parseStructDefinition(sourceText) {
  26. const source = stripComments(sourceText)
  27. const aliases = createAliasMap(source)
  28. const structInfo = findStruct(source)
  29. if (!structInfo) {
  30. throw new Error('未找到结构体定义')
  31. }
  32. const registers = parseStructFields(structInfo.body, aliases)
  33. if (!registers.length) {
  34. throw new Error('结构体中没有可识别的变量定义')
  35. }
  36. return {
  37. name: structInfo.name || 'Struct',
  38. registers,
  39. structName: structInfo.name || 'Struct'
  40. }
  41. }
  42. function getStructNameAliases(structInfo, aliases) {
  43. const names = [structInfo.name]
  44. if (structInfo.tagName) names.push(`struct ${structInfo.tagName}`)
  45. Object.keys(aliases || {}).forEach((aliasName) => {
  46. if (aliases[aliasName] === structInfo.name) names.push(aliasName)
  47. })
  48. return names.filter(Boolean)
  49. }
  50. function normalizeVariableTypeText(typeText, aliases) {
  51. const normalized = normalizeTypeText(typeText)
  52. if (!normalized) return ''
  53. const tokens = normalized
  54. .split(/\s+/)
  55. .filter((token) => !STRUCT_VARIABLE_QUALIFIERS[token])
  56. const compact = tokens.join(' ')
  57. if (aliases && aliases[compact]) return aliases[compact]
  58. return compact
  59. }
  60. function parseStructVariables(source, structs, aliases) {
  61. const variablesByName = {}
  62. structs.forEach((structInfo) => {
  63. const structNames = getStructNameAliases(structInfo, aliases)
  64. structNames.forEach((structName) => {
  65. const escaped = structName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  66. const variablePattern = new RegExp(`(^|[;\\n{}])\\s*([A-Za-z_][\\w\\s]*?\\s+)?${escaped}\\s+([^;{}()]+);`, 'g')
  67. let match
  68. while ((match = variablePattern.exec(source))) {
  69. const prefix = normalizeVariableTypeText(match[2] || '', aliases)
  70. if (prefix) continue
  71. splitDeclarators(match[3]).forEach((declaratorText) => {
  72. const field = parseDeclarator(declaratorText)
  73. if (!field) return
  74. const variableInfo = {
  75. arrayDimensions: field.arrayDimensions,
  76. name: field.name,
  77. registers: structInfo.registers,
  78. structName: structInfo.name
  79. }
  80. variablesByName[field.name] = variableInfo
  81. variablesByName[field.name.replace(/^_+/, '').toLowerCase()] = variableInfo
  82. variablesByName[normalizeLookupName(field.name)] = variableInfo
  83. })
  84. }
  85. })
  86. })
  87. return variablesByName
  88. }
  89. function parseStructCatalog(sourceText) {
  90. const source = stripComments(sourceText)
  91. const aliases = createAliasMap(source)
  92. const structs = findStructs(source).map((structInfo) => ({
  93. ...structInfo,
  94. registers: parseStructFields(structInfo.body, aliases)
  95. })).filter((structInfo) => structInfo.registers.length)
  96. if (!structs.length) {
  97. throw new Error('未找到可识别的结构体定义')
  98. }
  99. return {
  100. structs,
  101. variablesByName: parseStructVariables(source, structs, aliases)
  102. }
  103. }
  104. module.exports = {
  105. parseStructCatalog,
  106. parseStructDefinition,
  107. stripComments
  108. }