orWithNext, pointer cleanup

This commit is contained in:
Ganesh Viswanathan 2019-01-11 19:36:38 -06:00
commit a1d920bc6a
4 changed files with 84 additions and 46 deletions

View file

@ -36,12 +36,7 @@ proc saveNodeData(node: TSNode): bool =
if node.tsNodePrevNamedSibling().tsNodeIsNull() and if node.tsNodePrevNamedSibling().tsNodeIsNull() and
((node.isPName("pointer_declarator") and not node.isPPName("function_declarator")) or ((node.isPName("pointer_declarator") and not node.isPPName("function_declarator")) or
(node.getPName() in ["function_declarator", "array_declarator"] and node.isPPName("pointer_declarator"))): (node.getPName() in ["function_declarator", "array_declarator"] and node.isPPName("pointer_declarator"))):
if gStateRT.data[^1].val != "object": gStateRT.data.add(("pointer_declarator", ""))
gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier()
if gStateRT.data[^1].val == "ptr char":
gStateRT.data[^1].val = "cstring"
else:
gStateRT.data[^1].val = "pointer"
gStateRT.data.add((name, val)) gStateRT.data.add((name, val))

View file

@ -185,6 +185,8 @@ converter toString*(kind: Kind): string =
"*" "*"
of zeroOrOne: of zeroOrOne:
"?" "?"
of orWithNext:
"!"
converter toKind*(kind: string): Kind = converter toKind*(kind: string): Kind =
return case kind: return case kind:
@ -194,6 +196,8 @@ converter toKind*(kind: string): Kind =
zeroOrMore zeroOrMore
of "?": of "?":
zeroOrOne zeroOrOne
of "!":
orWithNext
else: else:
exactlyOne exactlyOne
@ -223,7 +227,12 @@ proc getRegexForAstChildren*(ast: ref Ast): string =
result = "^" result = "^"
for i in 0 .. ast.children.len-1: for i in 0 .. ast.children.len-1:
let kind: string = ast.children[i].kind let kind: string = ast.children[i].kind
result &= &"(?:{ast.children[i].name}){kind}" let begin = if result[^1] == '|': "" else: "(?:"
case kind:
of "!":
result &= &"{begin}{ast.children[i].name}|"
else:
result &= &"{begin}{ast.children[i].name}){kind}"
result &= "$" result &= "$"
proc getAstChildByName*(ast: ref Ast, name: string): ref Ast = proc getAstChildByName*(ast: ref Ast, name: string): ref Ast =

View file

@ -10,6 +10,7 @@ type
oneOrMore # + oneOrMore # +
zeroOrMore # * zeroOrMore # *
zeroOrOne # ? zeroOrOne # ?
orWithNext # !
Ast* = object Ast* = object
name*: string name*: string

View file

@ -50,18 +50,35 @@ proc initGrammar() =
""", """,
proc (ast: ref Ast, node: TSNode) = proc (ast: ref Ast, node: TSNode) =
var var
name = gStateRT.data[1].val.getIdentifier() i = 0
typ = gStateRT.data[0].val.getIdentifier() typ = gStateRT.data[i].val.getIdentifier()
name = ""
tptr = ""
i += 1
if i < gStateRT.data.len:
if gStateRT.data[i].name == "pointer_declarator":
tptr = "ptr "
i += 1
name = gStateRT.data[i].val.getIdentifier()
if name notin gStateRT.types: if name notin gStateRT.types:
gStateRT.types.add(name) gStateRT.types.add(name)
if name == typ: if name == typ or typ == "object":
typ = "object" gStateRT.typeStr &= &" {name}* = object\n"
gStateRT.typeStr &= &" {name}* = {typ}\n" else:
gStateRT.typeStr &= &" {name}* = {tptr}{typ}\n"
)) ))
template funcParamCommon(pname, ptyp, pout, count, i: untyped): untyped = template funcParamCommon(pname, ptyp, pptr, pout, count, i: untyped): untyped =
ptyp = gStateRT.data[i].val.getIdentifier() ptyp = gStateRT.data[i].val.getIdentifier()
if i+1 < gStateRT.data.len and gStateRT.data[i+1].name == "pointer_declarator":
pptr = "ptr "
i += 1
else:
pptr = ""
if i+1 < gStateRT.data.len and gStateRT.data[i+1].name == "identifier": if i+1 < gStateRT.data.len and gStateRT.data[i+1].name == "identifier":
pname = gStateRT.data[i+1].val.getIdentifier() pname = gStateRT.data[i+1].val.getIdentifier()
i += 2 i += 2
@ -70,7 +87,7 @@ proc initGrammar() =
count += 1 count += 1
i += 1 i += 1
if ptyp != "object": if ptyp != "object":
pout &= &"{pname}: {ptyp}," pout &= &"{pname}: {pptr}{ptyp},"
proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) = proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) =
var var
@ -100,25 +117,34 @@ proc initGrammar() =
var var
i = fstart i = fstart
ftyp, fname: string
fptr = ""
while i < gStateRT.data.len-fend: while i < gStateRT.data.len-fend:
fptr = ""
if gStateRT.data[i].name == "field_declaration": if gStateRT.data[i].name == "field_declaration":
i += 1 i += 1
continue continue
let if gStateRT.data[i].name notin ["field_identifier", "pointer_declarator"]:
ftyp = gStateRT.data[i].val.getIdentifier() ftyp = gStateRT.data[i].val.getIdentifier()
fname = gStateRT.data[i+1].val.getIdentifier() i += 1
if i+2 < gStateRT.data.len-fend and gStateRT.data[i+2].name in ["identifier", "number_literal"]:
if gStateRT.data[i].name == "pointer_declarator":
fptr = "ptr "
i += 1
fname = gStateRT.data[i].val.getIdentifier()
if i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name in ["identifier", "number_literal"]:
let let
flen = gStateRT.data[i+2].val.getIdentifier() flen = gStateRT.data[i+1].val.getIdentifier()
gStateRT.typeStr &= &" {fname}*: array[{flen}, {ftyp}]\n" gStateRT.typeStr &= &" {fname}*: array[{flen}, {fptr}{ftyp}]\n"
i += 3 i += 2
elif i+2 < gStateRT.data.len-fend and gStateRT.data[i+2].name == "function_declarator": elif i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name == "function_declarator":
var var
pout, pname, ptyp = "" pout, pname, ptyp, pptr = ""
count = 1 count = 1
i += 3 i += 2
while i < gStateRT.data.len-fend: while i < gStateRT.data.len-fend:
if gStateRT.data[i].name == "function_declarator": if gStateRT.data[i].name == "function_declarator":
i += 1 i += 1
@ -127,18 +153,18 @@ proc initGrammar() =
if gStateRT.data[i].name == "field_declaration": if gStateRT.data[i].name == "field_declaration":
break break
funcParamCommon(pname, ptyp, pout, count, i) funcParamCommon(pname, ptyp, pptr, pout, count, i)
if pout.len != 0 and pout[^1] == ',': if pout.len != 0 and pout[^1] == ',':
pout = pout[0 .. ^2] pout = pout[0 .. ^2]
if ftyp != "object": if ftyp != "object":
gStateRT.typeStr &= &" {fname}*: proc({pout}): {ftyp} {{.nimcall.}}\n" gStateRT.typeStr &= &" {fname}*: proc({pout}): {fptr}{ftyp} {{.nimcall.}}\n"
else: else:
gStateRT.typeStr &= &" {fname}*: proc({pout}) {{.nimcall.}}\n" gStateRT.typeStr &= &" {fname}*: proc({pout}) {{.nimcall.}}\n"
i += 1 i += 1
else: else:
gStateRT.typeStr &= &" {fname}*: {ftyp}\n" gStateRT.typeStr &= &" {fname}*: {fptr}{ftyp}\n"
i += 2 i += 1
let let
paramListGrammar = &""" paramListGrammar = &"""
@ -155,12 +181,12 @@ proc initGrammar() =
""" """
fieldGrammar = &""" fieldGrammar = &"""
(field_identifier?) (field_identifier!)
(array_declarator? (array_declarator!
(field_identifier) (field_identifier)
(identifier|number_literal) (identifier|number_literal)
) )
(function_declarator? (function_declarator+
(pointer_declarator (pointer_declarator
(field_identifier) (field_identifier)
) )
@ -172,10 +198,10 @@ proc initGrammar() =
(field_declaration_list (field_declaration_list
(field_declaration+ (field_declaration+
{typeGrammar} {typeGrammar}
{fieldGrammar} (pointer_declarator!
(pointer_declarator?
{fieldGrammar} {fieldGrammar}
) )
{fieldGrammar}
) )
) )
""" """
@ -295,7 +321,7 @@ proc initGrammar() =
)) ))
let funcGrammar = &""" let funcGrammar = &"""
(function_declarator* (function_declarator+
(identifier) (identifier)
{paramListGrammar} {paramListGrammar}
) )
@ -306,31 +332,31 @@ proc initGrammar() =
(declaration (declaration
(storage_class_specifier?) (storage_class_specifier?)
{typeGrammar} {typeGrammar}
{funcGrammar} (pointer_declarator!
(pointer_declarator*
{funcGrammar} {funcGrammar}
) )
{funcGrammar} {funcGrammar}
(pointer_declarator*
{funcGrammar}
)
) )
""", """,
proc (ast: ref Ast, node: TSNode) = proc (ast: ref Ast, node: TSNode) =
let
ftyp = gStateRT.data[0].val.getIdentifier()
var var
ftyp = gStateRT.data[0].val.getIdentifier()
fptr = ""
i = 1 i = 1
while i < gStateRT.data.len: while i < gStateRT.data.len:
if gStateRT.data[i].name == "function_declarator": if gStateRT.data[i].name == "function_declarator":
i += 1 i += 1
continue continue
if gStateRT.data[i].name == "pointer_declarator":
fptr = "ptr "
i += 1
var var
fname = gStateRT.data[i].val fname = gStateRT.data[i].val
fnname = fname.getIdentifier() fnname = fname.getIdentifier()
pout, pname, ptyp = "" pout, pname, ptyp, pptr = ""
count = 1 count = 1
i += 1 i += 1
@ -338,7 +364,7 @@ proc initGrammar() =
if gStateRT.data[i].name == "function_declarator": if gStateRT.data[i].name == "function_declarator":
break break
funcParamCommon(pname, ptyp, pout, count, i) funcParamCommon(pname, ptyp, pptr, pout, count, i)
if pout.len != 0 and pout[^1] == ',': if pout.len != 0 and pout[^1] == ',':
pout = pout[0 .. ^2] pout = pout[0 .. ^2]
@ -346,7 +372,7 @@ proc initGrammar() =
if fnname notin gStateRT.procs: if fnname notin gStateRT.procs:
gStateRT.procs.add(fnname) gStateRT.procs.add(fnname)
if ftyp != "object": if ftyp != "object":
gStateRT.procStr &= &"proc {fnname}*({pout}): {ftyp} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" gStateRT.procStr &= &"proc {fnname}*({pout}): {fptr}{ftyp} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n"
else: else:
gStateRT.procStr &= &"proc {fnname}*({pout}) {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" gStateRT.procStr &= &"proc {fnname}*({pout}) {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n"
@ -357,7 +383,14 @@ proc initRegex(ast: ref Ast) =
for child in ast.children: for child in ast.children:
child.initRegex() child.initRegex()
ast.regex = ast.getRegexForAstChildren().re() var
reg: string
try:
reg = ast.getRegexForAstChildren()
ast.regex = reg.re()
except:
echo reg
raise newException(Exception, getCurrentExceptionMsg())
proc parseGrammar*() = proc parseGrammar*() =
initGrammar() initGrammar()