aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO1
-rw-r--r--filetypes/makefilecom.py12
-rw-r--r--filetypes/makefiles.py168
3 files changed, 98 insertions, 83 deletions
diff --git a/TODO b/TODO
index fe08631..f72f780 100644
--- a/TODO
+++ b/TODO
@@ -9,3 +9,4 @@ Perhaps multithread some stuff so the rest of the program doesn't have to wait f
Handle deptopackage conversion where the dep is defined at root lever IE dep = /usr/map/file
Handle ../map/%.type : %.type2 makefile targets
Handle zip,tar for unpacking
+Handle $(foo)_test = ... variable assingment
diff --git a/filetypes/makefilecom.py b/filetypes/makefilecom.py
index 99b8180..83e00bf 100644
--- a/filetypes/makefilecom.py
+++ b/filetypes/makefilecom.py
@@ -6,7 +6,7 @@ def expand(lst,variables):
for item in lst:
if isinstance(item, list):
strlst = com_interp(item[0],variables)
- netlst += expand(strlst,variables)
+ newlst += expand(strlst,variables)
else:
newlst.append(item)
@@ -110,7 +110,7 @@ def com_interp(string,variables):
def p_complst(p):
"complst : BEGINCOM textstr ENDCOM"
- p[0] = variables[p[2]]
+ p[0] = expand(variables[p[2]],variables)
def p_tonewstr(p):
"""
@@ -216,13 +216,13 @@ def com_interp(string,variables):
def p_spacelst(p):
"""
- spacelst : spacelst SPACE
+ spacestr : spacestr SPACE
| SPACE
"""
if len(p) == 3:
- p[0] = p[1] + [p[2]]
+ p[0] = p[1] + p[2]
else:
- p[0] = [p[1]]
+ p[0] = p[1]
def p_error(p):
print("syntax error at '%s'" % p.type,p.lexpos)
@@ -236,4 +236,4 @@ def com_interp(string,variables):
return retlst
-print(com_interp("($(${x}))",{"x":["y"], "y":["z"], "z":["u"],"yz":["u","v"]}))
+print(com_interp("($($(x)))",{"x":["y"], "y":["z"], "z":["u"],"yz":["u","v"]}))
diff --git a/filetypes/makefiles.py b/filetypes/makefiles.py
index 706fe2c..07381d3 100644
--- a/filetypes/makefiles.py
+++ b/filetypes/makefiles.py
@@ -3,9 +3,8 @@ from ply import yacc
from makefilecom import expand
def scanmakefile(makefile):
+ makefile = "\n" + makefile #Add \n so you can guess vars
tokens = (
- "VAR",
- "DOTVAR",
"END",
"COL",
"SEMICOL",
@@ -19,11 +18,13 @@ def scanmakefile(makefile):
"ENDTAB",
"LIT",
"COMMA",
+ "SPACE",
)
states = (
("com", "exclusive"),
("ccode", "exclusive"), #command code
+ ("var", "inclusive"),
)
# Match the first $(. Enter ccode state.
@@ -31,7 +32,7 @@ def scanmakefile(makefile):
r'\$(\{|\()'
t.lexer.code_start = t.lexer.lexpos # Record the starting position
t.lexer.level = 1 # Initial level
- t.lexer.begin('ccode') # Enter 'ccode' state
+ t.lexer.push_state('ccode') # Enter 'ccode' state
# Rules for the ccode state
def t_ccode_newcom(t):
@@ -46,7 +47,7 @@ def scanmakefile(makefile):
if t.lexer.level == 0:
t.value = t.lexer.lexdata[t.lexer.code_start-1:t.lexer.lexpos]
t.type = "COMMAND"
- t.lexer.begin('INITIAL')
+ t.lexer.pop_state()
return t
def t_ccode_text(t):
@@ -71,14 +72,6 @@ def scanmakefile(makefile):
t.lexer.lineno += 1
return t
- def t_EQ(t):
- r"="
- return t
-
- def t_COL(t):
- r":"
- return t
-
def t_SEMICOL(t):
r";"
return t
@@ -91,29 +84,32 @@ def scanmakefile(makefile):
r"\%"
return t
- def t_PEQ(t):
- r"[a-zA-Z_][a-zA-Z0-9_]*[ \t]*\+="
- t.value = t.value.split()[0].rstrip("+=")
+ def t_var_TEXT(t):
+ r"[^ \n\t\$\\,]+"
return t
- def t_CEQ(t):
- r"[a-zA-Z_][a-zA-Z0-9_]*[ \t]*:="
- t.value = t.value.split()[0].rstrip(":=")
+ def t_var_SPACE(t):
+ r"[ \t]"
return t
- def t_QEQ(t):
- r"[a-zA-Z_][a-zA-Z0-9_]*[ \t]*\?="
- t.value = t.value.split()[0].rstrip("?=")
+ def t_EQ(t):
+ r"=[ \t]*"
+ t.lexer.begin('var')
return t
- def t_VAR(t):
- r"[a-zA-Z_][a-zA-Z0-9_]*[ \t]*="
- t.value = t.value.split()[0].rstrip("=") #get the name of the var
+ def t_PEQ(t):
+ r"\+=[ \t]*"
+ t.lexer.begin('var')
+ return t
+
+ def t_CEQ(t):
+ r":=[ \t]*"
+ t.lexer.begin('var')
return t
- def t_DOTVAR(t):
- r"\.[a-zA-Z_][a-zA-Z0-9_]*[ \t]*="
- t.value = t.value.split()[0].rstrip("=") #get the name of the var
+ def t_QEQ(t):
+ r"\?=[ \t]*"
+ t.lexer.begin('var')
return t
def t_contline(t):
@@ -126,6 +122,10 @@ def scanmakefile(makefile):
t.value = t.value[1] #take the literal char
return t
+ def t_COL(t):
+ r":"
+ return t
+
def t_COMMA(t):
r","
return t
@@ -140,12 +140,13 @@ def scanmakefile(makefile):
return t
def t_TEXT(t):
- r"[^ \n\t:\\,]+"
+ r"[^ \n\t:\?\+=\\,]+"
return t
def t_END(t):
r"\n+"
t.lexer.lineno += t.value.count('\n')
+ t.lexer.begin('INITIAL')
return t
def t_ANY_error(t):
@@ -166,95 +167,108 @@ def scanmakefile(makefile):
ivars = [] #keep track of the immediate variables
targets = [] #buildtargets, [[target,deps,options],[target2,....
- def p_target(p):
-
def p_peq(p): #immediate if peq was defined as immediate before else deferred
"""
- end : end PEQ textlst end
- | PEQ textlst end
+ end : end textstr PEQ textlst end
+ | end textstr PEQ end
"""
- if len(p) == 4:
- if not p[1] in variables:
- variables[p[1]] = p[2]
- elif not p[1] in ivars:
- variables[p[1]] += p[2]
+ if len(p) == 6:
+ if not p[2] in variables:
+ variables[p[2]] = p[4]
+ elif not p[2] in ivars:
+ variables[p[2]] += p[4]
else:
- textvalue = expand(p[2]) #expand any variables
- variables[p[1]] = textvalue
-
- elif not p[2] in variables:
- variables[p[2]] = p[3]
- elif not p[2] in ivars:
- variables[p[2]] += p[3]
- else:
- textvalue = expand(p[3]) #expand any variables
- variables[p[2]] = textvalue
+ textvalue = expand(p[4],variables) #expand any variables
+ variables[p[2]] = textvalue
def p_ceq(p): #immediate
"""
- end : end CEQ textlst end
- | CEQ textlst end
+ end : end textstr CEQ textlst end
+ | end textstr CEQ end
"""
- if len(p) == 4:
- textvalue = expand(p[2]) #expand any variables
- variables[p[1]] = textvalue
- ivars.append(p[1])
- else:
- textvalue = expand(p[3]) #expand any variables
+ if len(p) == 6:
+ print(p[4])
+ textvalue = expand(p[4],variables) #expand any variables
variables[p[2]] = textvalue
ivars.append(p[2])
+ else:
+ variables[p[2]] = []
+ ivars.append(p[2])
def p_qeq(p): #deferred
"""
- end : end QEQ textlst end
- | QEQ textlst end
+ end : end textstr QEQ textlst end
+ | end textstr QEQ end
"""
- if len(p) == 4 and not p[1] in variables:
- variables[p[1]] = p[2]
- elif not p[2] in variables:
- variables[p[2]] = p[3]
+ if not p[2] in variables and len(p) == 6:
+ variables[p[2]] = p[4]
+ else:
+ variables[p[2]] = []
def p_var(p): #deferred
"""
- end : end VAR textlst end
- | VAR textlst end
+ end : end textstr EQ textlst end
+ | end textstr EQ end
"""
- if len(p) == 4:
- variables[p[1]] = p[2]
+ if len(p) == 6:
+ variables[p[2]] = p[4]
else:
- variables[p[2]] = p[3]
+ variables[p[2]] = []
def p_textlst(p):
"""
- textlst : textlst TEXT
- | textlst command
- | textlst LIT
+ textlst : textlst spacestr command
+ | textlst spacestr textstr
| command
+ | textstr
+ """
+ if len(p) == 4:
+ p[0] = p[1]+ [p[3]]
+ else:
+ p[0] = [p[1]]
+
+ def p_textstr(p):
+ """
+ textstr : textstr LIT
| TEXT
| LIT
"""
if len(p) == 3:
- p[0] = p[1].append(p[2])
+ p[0] = p[1] + p[2]
else:
- p[0] = [p[1]]
+ p[0] = p[1]
def p_command(p):
- "command: COMMAND"
+ "command : COMMAND"
p[0] = [p[1]] #commands are lists within the testlst
def p_end(p):
"""
- end : END
- | end END
+ end : end END
+ | spacestr END
+ | END
"""
+ def p_space(p):
+ """
+ spacestr : spacestr SPACE
+ | SPACE
+ """
+ if len(p) == 3:
+ p[0] = p[1] + p[2]
+ else:
+ p[0] = p[1]
+
+
def p_error(p):
print("syntax error at '%s'" % p.type,p.lexpos)
pass
- #yacc.yacc()
+ yacc.yacc()
+
+ yacc.parse(makefile)
- #yacc.parse(makefile)
+ print(variables)
#for target in targets:
# print(target)
@@ -267,7 +281,7 @@ def scanmakefile(makefile):
#deferred
-file="Makefile2"
+file="Makefile"
with open(file, encoding="utf-8", errors="replace") as inputfile:
scanmakefile(inputfile.read())