Compare commits
1 commit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd8a263f85 |
7 changed files with 75 additions and 38 deletions
|
|
@ -4,18 +4,6 @@ import regex
|
|||
|
||||
import "."/[getters, globals, grammar, treesitter/runtime]
|
||||
|
||||
const gAtoms = @[
|
||||
"field_identifier",
|
||||
"identifier",
|
||||
"shift_expression",
|
||||
"math_expression",
|
||||
"number_literal",
|
||||
"preproc_arg",
|
||||
"primitive_type",
|
||||
"sized_type_specifier",
|
||||
"type_identifier"
|
||||
].toSet()
|
||||
|
||||
proc saveNodeData(node: TSNode): bool =
|
||||
let name = $node.tsNodeType()
|
||||
if name in gAtoms:
|
||||
|
|
@ -25,10 +13,10 @@ proc saveNodeData(node: TSNode): bool =
|
|||
if name == "primitive_type" and node.tsNodeParent.tsNodeType() == "sized_type_specifier":
|
||||
return true
|
||||
|
||||
if name == "number_literal" and $node.tsNodeParent.tsNodeType() in ["shift_expression", "math_expression"]:
|
||||
if name == "number_literal" and $node.tsNodeParent.tsNodeType() in gExpressions:
|
||||
return true
|
||||
|
||||
if name in ["math_expression", "primitive_type", "sized_type_specifier"]:
|
||||
if name in ["primitive_type", "sized_type_specifier"]:
|
||||
val = val.getType()
|
||||
|
||||
let
|
||||
|
|
@ -52,6 +40,10 @@ proc saveNodeData(node: TSNode): bool =
|
|||
ppname == "function_declarator":
|
||||
gStateRT.data.add(("function_declarator", ""))
|
||||
|
||||
elif name in gExpressions:
|
||||
if $node.tsNodeParent.tsNodeType() notin gExpressions:
|
||||
gStateRT.data.add((name, node.getNodeVal()))
|
||||
|
||||
elif name in ["abstract_pointer_declarator", "enumerator", "field_declaration", "function_declarator"]:
|
||||
gStateRT.data.add((name.replace("abstract_", ""), ""))
|
||||
|
||||
|
|
@ -65,14 +57,19 @@ proc searchAstForNode(ast: ref Ast, node: TSNode): bool =
|
|||
return
|
||||
|
||||
if ast.children.len != 0:
|
||||
if childNames.contains(ast.regex):
|
||||
if childNames.contains(ast.regex) or
|
||||
(childNames.len == 0 and ast.recursive):
|
||||
if node.getTSNodeNamedChildCountSansComments() != 0:
|
||||
var flag = true
|
||||
for i in 0 .. node.tsNodeNamedChildCount()-1:
|
||||
if $node.tsNodeNamedChild(i).tsNodeType() != "comment":
|
||||
let
|
||||
nodeChild = node.tsNodeNamedChild(i)
|
||||
astChild = ast.getAstChildByName($nodeChild.tsNodeType())
|
||||
astChild =
|
||||
if not ast.recursive:
|
||||
ast.getAstChildByName($nodeChild.tsNodeType())
|
||||
else:
|
||||
ast
|
||||
if not searchAstForNode(astChild, nodeChild):
|
||||
flag = false
|
||||
break
|
||||
|
|
|
|||
|
|
@ -236,12 +236,16 @@ converter toKind*(kind: string): Kind =
|
|||
else:
|
||||
exactlyOne
|
||||
|
||||
proc getNameKind*(name: string): tuple[name: string, kind: Kind] =
|
||||
result.name = name
|
||||
proc getNameKind*(name: string): tuple[name: string, kind: Kind, recursive: bool] =
|
||||
if name[0] == '^':
|
||||
result.recursive = true
|
||||
result.name = name[1 .. ^1]
|
||||
else:
|
||||
result.name = name
|
||||
result.kind = $name[^1]
|
||||
|
||||
if result.kind != exactlyOne:
|
||||
result.name = name[0 .. ^2]
|
||||
result.name = result.name[0 .. ^2]
|
||||
|
||||
proc getTSNodeNamedChildCountSansComments*(node: TSNode): int =
|
||||
if node.tsNodeNamedChildCount() != 0:
|
||||
|
|
@ -261,8 +265,9 @@ proc getTSNodeNamedChildNames*(node: TSNode): seq[string] =
|
|||
proc getRegexForAstChildren*(ast: ref Ast): string =
|
||||
result = "^"
|
||||
for i in 0 .. ast.children.len-1:
|
||||
let kind: string = ast.children[i].kind
|
||||
let begin = if result[^1] == '|': "" else: "(?:"
|
||||
let
|
||||
kind: string = ast.children[i].kind
|
||||
begin = if result[^1] == '|': "" else: "(?:"
|
||||
case kind:
|
||||
of "!":
|
||||
result &= &"{begin}{ast.children[i].name}|"
|
||||
|
|
|
|||
|
|
@ -1,10 +1,33 @@
|
|||
import sets, tables
|
||||
import sequtils, sets, tables
|
||||
|
||||
import regex
|
||||
|
||||
when not declared(CIMPORT):
|
||||
import "."/treesitter/runtime
|
||||
|
||||
const
|
||||
gAtoms* = @[
|
||||
"field_identifier",
|
||||
"identifier",
|
||||
"number_literal",
|
||||
"preproc_arg",
|
||||
"primitive_type",
|
||||
"sized_type_specifier",
|
||||
"type_identifier"
|
||||
].toSet()
|
||||
|
||||
gExpressions* = @[
|
||||
"parenthesized_expression",
|
||||
"bitwise_expression",
|
||||
"shift_expression",
|
||||
"math_expression"
|
||||
].toSet()
|
||||
|
||||
gEnumVals* = @[
|
||||
"identifier",
|
||||
"number_literal"
|
||||
].concat(toSeq(gExpressions.items))
|
||||
|
||||
type
|
||||
Kind* = enum
|
||||
exactlyOne
|
||||
|
|
@ -16,6 +39,7 @@ type
|
|||
Ast* = object
|
||||
name*: string
|
||||
kind*: Kind
|
||||
recursive*: bool
|
||||
children*: seq[ref Ast]
|
||||
when not declared(CIMPORT):
|
||||
tonim*: proc (ast: ref Ast, node: TSNode)
|
||||
|
|
|
|||
|
|
@ -325,14 +325,15 @@ proc initGrammar() =
|
|||
|
||||
if gStateRT.consts.addNewIdentifer(fname):
|
||||
if i+1 < gStateRT.data.len-fend and
|
||||
gStateRT.data[i+1].name in ["identifier", "shift_expression", "math_expression", "number_literal"]:
|
||||
if " " in gStateRT.data[i+1].val:
|
||||
gStateRT.data[i+1].val = "(" & gStateRT.data[i+1].val.replace(" ", "") & ")"
|
||||
gStateRT.data[i+1].name in gEnumVals:
|
||||
gStateRT.data[i+1].val = gStateRT.data[i+1].val.multiReplace([
|
||||
("<<", " shl "), (">>", " shr ")
|
||||
(" ", ""),
|
||||
("<<", " shl "), (">>", " shr "),
|
||||
("^", " xor "), ("&", " and "), ("|", " or "),
|
||||
("~", " not ")
|
||||
])
|
||||
|
||||
gStateRT.constStr &= &" {fname}* = {gStateRT.data[i+1].val}.{nname}\n"
|
||||
gStateRT.constStr &= &" {fname}* = ({gStateRT.data[i+1].val}).{nname}\n"
|
||||
try:
|
||||
count = gStateRT.data[i+1].val.parseInt() + 1
|
||||
except:
|
||||
|
|
@ -349,15 +350,12 @@ proc initGrammar() =
|
|||
(type_identifier?)
|
||||
(enumerator_list
|
||||
(enumerator+
|
||||
(identifier+)
|
||||
(number_literal?)
|
||||
(shift_expression|math_expression?
|
||||
(number_literal+)
|
||||
)
|
||||
(identifier?)
|
||||
(^$1+)
|
||||
)
|
||||
)
|
||||
)
|
||||
""",
|
||||
""" % gEnumVals.join("|"),
|
||||
proc (ast: ref Ast, node: TSNode) =
|
||||
var
|
||||
name = ""
|
||||
|
|
@ -439,8 +437,9 @@ proc initGrammar() =
|
|||
|
||||
proc initRegex(ast: ref Ast) =
|
||||
if ast.children.len != 0:
|
||||
for child in ast.children:
|
||||
child.initRegex()
|
||||
if not ast.recursive:
|
||||
for child in ast.children:
|
||||
child.initRegex()
|
||||
|
||||
var
|
||||
reg: string
|
||||
|
|
|
|||
|
|
@ -34,8 +34,10 @@ proc readFromTokens(): ref Ast =
|
|||
quit(1)
|
||||
if gTokens[idx+1] != "comment":
|
||||
result = new(Ast)
|
||||
(result.name, result.kind) = gTokens[idx+1].getNameKind()
|
||||
(result.name, result.kind, result.recursive) = gTokens[idx+1].getNameKind()
|
||||
result.children = @[]
|
||||
if result.recursive:
|
||||
result.children.add(result)
|
||||
idx += 2
|
||||
while gTokens[idx] != ")":
|
||||
var res = readFromTokens()
|
||||
|
|
@ -48,9 +50,9 @@ proc readFromTokens(): ref Ast =
|
|||
idx += 1
|
||||
|
||||
proc printAst*(node: ref Ast, offset=""): string =
|
||||
result = offset & "(" & node.name & node.kind.toString()
|
||||
result = offset & "(" & (if node.recursive: "^" else: "") & node.name & node.kind.toString()
|
||||
|
||||
if node.children.len != 0:
|
||||
if node.children.len != 0 and not node.recursive:
|
||||
result &= "\n"
|
||||
for child in node.children:
|
||||
result &= printAst(child, offset & " ")
|
||||
|
|
|
|||
|
|
@ -60,6 +60,12 @@ typedef enum ENUM4 {
|
|||
enum12
|
||||
} ENUM4;
|
||||
|
||||
enum ENUM5 {
|
||||
enum13 = (1 << 2),
|
||||
enum14 = ((1 << 3) | 1),
|
||||
enum15 = (1 << (1 & 1))
|
||||
};
|
||||
|
||||
typedef void * VOIDPTR;
|
||||
typedef int * INTPTR;
|
||||
|
||||
|
|
|
|||
|
|
@ -97,6 +97,10 @@ else:
|
|||
check e3 == enum7
|
||||
check e4 == enum11
|
||||
|
||||
check enum13 == 4
|
||||
check enum14 == 9
|
||||
check enum15 == 2
|
||||
|
||||
cAddStdDir()
|
||||
|
||||
## failing tests
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue