| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- const TYPE_ALIASES = {
- bit: 'uint8_t',
- bool: 'uint8_t',
- char: 'int8_t',
- double: 'float',
- float: 'float',
- int: 'int16_t',
- int8: 'int8_t',
- int8_t: 'int8_t',
- int16: 'int16_t',
- int16_t: 'int16_t',
- int32: 'int32_t',
- int32_t: 'int32_t',
- long: 'int32_t',
- short: 'int16_t',
- 'signed char': 'int8_t',
- 'signed int': 'int16_t',
- 'signed long': 'int32_t',
- 'signed short': 'int16_t',
- uint8: 'uint8_t',
- uint8_t: 'uint8_t',
- uint16: 'uint16_t',
- uint16_t: 'uint16_t',
- uint32: 'uint32_t',
- uint32_t: 'uint32_t',
- 'unsigned char': 'uint8_t',
- 'unsigned int': 'uint16_t',
- 'unsigned long': 'uint32_t',
- 'unsigned short': 'uint16_t'
- }
- const TYPE_QUALIFIERS = {
- _I: true,
- _IO: true,
- _O: true,
- const: true,
- extern: true,
- register: true,
- static: true,
- volatile: true
- }
- const STRUCT_PATTERNS = [
- /typedef\s+struct(?:\s+[A-Za-z_]\w*)?\s*\{([\s\S]*?)\}\s*([A-Za-z_]\w*)\s*;/g,
- /struct\s+([A-Za-z_]\w*)\s*\{([\s\S]*?)\}\s*;/g
- ]
- function normalizeLookupName(value) {
- return String(value || '')
- .replace(/^_+/, '')
- .replace(/[^A-Za-z0-9]/g, '')
- .toLowerCase()
- }
- function stripComments(source) {
- return String(source || '')
- .replace(/\/\*[\s\S]*?\*\//g, '')
- .replace(/\/\/.*$/gm, '')
- }
- function normalizeTypeText(typeText) {
- return String(typeText || '')
- .replace(/\*/g, ' ')
- .replace(/\s+/g, ' ')
- .trim()
- }
- function resolveType(typeText, aliases) {
- const normalized = normalizeTypeText(typeText)
- if (!normalized) return ''
- const compact = normalized
- .split(/\s+/)
- .filter((token) => !TYPE_QUALIFIERS[token])
- .join(' ')
- .trim()
- if (!compact || /^struct\b/.test(compact) || /^enum\b/.test(compact) || compact.indexOf('*') >= 0) {
- return ''
- }
- if (aliases[compact]) return aliases[compact]
- const tokens = compact.split(/\s+/).filter(Boolean)
- for (const token of tokens) {
- if (aliases[token]) return aliases[token]
- }
- return ''
- }
- function createAliasMap(source) {
- const aliases = {
- ...TYPE_ALIASES
- }
- const definePattern = /^\s*#\s*define\s+([A-Za-z_]\w*)\s+([A-Za-z_]\w*)\s*$/gm
- let defineMatch
- while ((defineMatch = definePattern.exec(source))) {
- const name = defineMatch[1]
- const value = defineMatch[2]
- if (aliases[value]) aliases[name] = aliases[value]
- }
- const typedefPattern = /typedef\s+(?!struct\b)([^;{}]+?)\s+([A-Za-z_]\w*)\s*;/g
- let typedefMatch
- while ((typedefMatch = typedefPattern.exec(source))) {
- const resolvedType = resolveType(typedefMatch[1], aliases)
- if (resolvedType) aliases[typedefMatch[2]] = resolvedType
- }
- const typedefStructPattern = /typedef\s+struct(?:\s+([A-Za-z_]\w*))?\s*\{[\s\S]*?\}\s*([A-Za-z_]\w*)\s*;/g
- let structTypedefMatch
- while ((structTypedefMatch = typedefStructPattern.exec(source))) {
- const tagName = structTypedefMatch[1]
- const typedefName = structTypedefMatch[2]
- if (tagName && typedefName) aliases[`struct ${tagName}`] = typedefName
- }
- return aliases
- }
- function findStruct(source) {
- for (const pattern of STRUCT_PATTERNS) {
- pattern.lastIndex = 0
- const match = pattern.exec(source)
- if (!match) continue
- if (pattern === STRUCT_PATTERNS[0]) {
- return {
- body: match[1],
- name: match[2]
- }
- }
- return {
- body: match[2],
- name: match[1]
- }
- }
- return null
- }
- function findStructs(source) {
- const structs = []
- STRUCT_PATTERNS.forEach((pattern) => {
- pattern.lastIndex = 0
- let match
- while ((match = pattern.exec(source))) {
- if (pattern === STRUCT_PATTERNS[0]) {
- structs.push({
- body: match[1],
- name: match[2]
- })
- } else {
- structs.push({
- body: match[2],
- name: match[1],
- tagName: match[1]
- })
- }
- }
- })
- const seen = {}
- return structs.filter((item) => {
- const key = item.name
- if (!key || seen[key]) return false
- seen[key] = true
- return true
- })
- }
- function parseArrayDimensions(suffix) {
- const dimensions = []
- const pattern = /\[([^\]]*)\]/g
- let match
- while ((match = pattern.exec(suffix || ''))) {
- const text = String(match[1] || '').trim()
- const value = Number(text)
- if (!Number.isInteger(value) || value < 1) {
- throw new Error('数组长度需为正整数')
- }
- dimensions.push(value)
- }
- return dimensions
- }
- function splitDeclarations(body) {
- return String(body || '')
- .split(';')
- .map((item) => item.trim())
- .filter(Boolean)
- }
- function splitDeclarators(statement) {
- return String(statement || '')
- .split(',')
- .map((item) => item.trim())
- .filter(Boolean)
- }
- function parseFirstDeclarator(text) {
- const match = String(text || '').match(/^(.+?)\s+(\**\s*(?:[A-Za-z_]\w*)?(?:\s*\[[^\]]*\])*(?:\s*:\s*\d+)?)$/)
- if (!match) return null
- return {
- declarator: match[2],
- typeText: match[1]
- }
- }
- function parseDeclarator(text) {
- const rawText = String(text || '')
- const bitWidthMatch = rawText.match(/:\s*(\d+)\s*$/)
- const cleaned = rawText
- .replace(/=.*/, '')
- .replace(/:\s*\d+\s*$/, '')
- .replace(/\*/g, '')
- .trim()
- if (!cleaned && bitWidthMatch) {
- return {
- arrayDimensions: [],
- bitWidth: Number(bitWidthMatch[1]),
- name: ''
- }
- }
- const match = cleaned.match(/^([A-Za-z_]\w*)\s*((?:\[[^\]]*\])*)$/)
- if (!match) return null
- return {
- arrayDimensions: parseArrayDimensions(match[2]),
- bitWidth: bitWidthMatch ? Number(bitWidthMatch[1]) : null,
- name: match[1]
- }
- }
- module.exports = {
- createAliasMap,
- findStruct,
- findStructs,
- normalizeLookupName,
- normalizeTypeText,
- parseDeclarator,
- parseFirstDeclarator,
- resolveType,
- splitDeclarations,
- splitDeclarators,
- stripComments
- }
|