Skip to content

Commit

Permalink
unbreaking the Rascal extractor; multiple Halstead metrics
Browse files Browse the repository at this point in the history
git-svn-id: https://slps.svn.sourceforge.net/svnroot/slps@937 ab42f6e0-554d-0410-b580-99e487e6eeb2
  • Loading branch information
grammarware committed Feb 3, 2011
1 parent d89cae9 commit 59ee138
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 70 deletions.
54 changes: 46 additions & 8 deletions shared/python/metrics.py
Expand Up @@ -248,7 +248,7 @@ def mccabe(node):
elif node.__class__.__name__ in ('Terminal','Nonterminal','Epsilon','Any','Empty','Value'):
return 0
elif node.__class__.__name__ == 'Choice':
return len(node.data)-1 + max(map(mccabe,node.data))
return len(node.data)-1 + sum(map(mccabe,node.data))
elif node.__class__.__name__ == 'Sequence':
return sum(map(mccabe,node.data))
else:
Expand Down Expand Up @@ -371,12 +371,50 @@ def allOperators(node):
print 'How to deal with',node.__class__.__name__,'?'
return 0

def HAL(g):
# Halstead preparations
def hal_mu1(g):
# Number of unique operators
# Selectable, Marked, Plus, Star, Optional, Epsilon, Empty, Any, Choice, Sequence
#mu1 = 10
mu1 = len(allOperators(g))
mu2 = VAR(g) + TERM(g) + VAL(g) + LAB(g)
eta1 = opr(g)
eta2 = opd(g)
hal = (mu1*eta2*(eta1+eta2)*math.log(mu1+mu2,2)) / (2*mu2)
return int(round(hal))
return len(allOperators(g))
def hal_mu2(g):
# Number of unique operands
return VAR(g) + TERM(g) + VAL(g) + LAB(g)
def hal_eta1(g):
# Total occurrences of operators
return opr(g)
def hal_eta2(g):
# Total occurrences of operands
return opd(g)

# HALEN - Halstead length
def HALEN(g):
eta1 = hal_eta1(g)
eta2 = hal_eta2(g)
hal = eta1 + eta2
return hal

# HAVOC - Halstead vocabulary
def HAVOC(g):
mu1 = hal_mu1(g)
mu2 = hal_mu2(g)
hal = mu1 + mu2
return hal

# HAVOL - Halstead volume
def HAVOL(g):
hal = HALEN(g)*math.log(HAVOC(g),2)
return hal

# HADIF - Halstead difficulty
def HADIF(g):
mu1 = hal_mu1(g)
mu2 = hal_mu2(g)
eta2 = hal_eta2(g)
hal = (mu1*eta2) / (2.0*mu2)
return hal

# HADIF - Halstead effort
def HAEFF(g):
hal = HADIF(g)*HAVOL(g)
return hal
6 changes: 4 additions & 2 deletions topics/extraction/rascal/Makefile
Expand Up @@ -2,15 +2,17 @@ all:
echo 'Extracting the actual grammar...'
./extract.py RascalRascal.rsc rascal.bgf
../../../shared/tools/validate bgf rascal.bgf
../../../shared/tools/subgrammar rascal.bgf Module rascal.true.bgf
../../../shared/tools/subgrammar rascal.bgf Module PreModule Command rascal.true.bgf
../../../shared/tools/validate bgf rascal.true.bgf
../../../shared/tools/bgf2bnf rascal.bgf rascal.bnf
../../../shared/tools/bgf2bnf rascal.true.bgf rascal.true.bnf
../../../shared/tools/bgf2html rascal.true.bgf rascal.true.html

hor:
echo 'Recovering the horizontal grammar...'
../../../shared/tools/xbgf horizontalize.xbgf rascal.bgf rascal.hor.bgf
../../../shared/tools/validate bgf rascal.hor.bgf
../../../shared/tools/subgrammar rascal.hor.bgf Module rascal.true.hor.bgf
../../../shared/tools/subgrammar rascal.hor.bgf Module PreModule Command rascal.true.hor.bgf
../../../shared/tools/validate bgf rascal.true.hor.bgf
../../../shared/tools/bgf2bnf rascal.hor.bgf rascal.hor.bnf
../../../shared/tools/bgf2bnf rascal.true.hor.bgf rascal.true.hor.bnf
Expand Down
22 changes: 20 additions & 2 deletions topics/extraction/rascal/extract.py
Expand Up @@ -46,6 +46,13 @@ def parseGroup(g):
print '['+str(cx)+']','Found first line, but of what nonterminal?'
continue
tokens = line[1:].split()
if len(tokens[-1])>1 and tokens[-1][-1] == ';':
tokens[-1] = tokens[-1][:-1]
tokens.append(';')
for i in range(0,len(tokens)):
if tokens[i].find('[')>-1 and tokens[i].find(']')>-1:
# treating a parametrised nonterminal as a base nonterminal
tokens[i] = tokens[i][:tokens[i].index('[')] + tokens[i][tokens[i].index(']')+1:]
grammar[nt].append(tokens)
continue
elif line[0] == '#':
Expand Down Expand Up @@ -73,6 +80,9 @@ def parseGroup(g):
print '['+str(cx)+']','Cannot include lexical restriction information about',nt
nt = ''
continue
if nt.find('[')>-1 and nt.find(']')>-1:
# treating a parametrised nonterminal as a base nonterminal
nt = nt[:nt.index('[')] + nt[nt.index(']')+1:]
print '['+str(cx)+']','Starting to treat nonterminal',nt
grammar[nt] = []
continue
Expand Down Expand Up @@ -101,11 +111,19 @@ def parseGroup(g):
prod.setNT(nt)
while alt and alt[0] in ('bracket','left','right','non-assoc','lex','(',')'):
print 'Skipped a modifier',alt[0],'at',nt
alt = alt[1:]
if alt[0] == 'lex':
alt = []
else:
alt = alt[1:]
if not alt:
continue
if alt[-1] == ';':
while len(alt)>0 and alt[-1] in (';',''):
alt = alt[:-1]
while len(alt)>0 and alt[0] == '':
alt = alt[1:]
#print '---',alt
if not alt:
continue
if alt[0][-1] == ':':
prod.setLabel(alt[0][:-1])
alt = alt[1:]
Expand Down
57 changes: 0 additions & 57 deletions topics/extraction/rascal/horizontalize.xbgf
Expand Up @@ -12,18 +12,12 @@
<xbgf:horizontal>
<nonterminal>BasicType</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>BooleanLiteral</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>Case</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>Catch</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>Char</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>CharClass</nonterminal>
</xbgf:horizontal>
Expand All @@ -42,27 +36,12 @@
<xbgf:horizontal>
<nonterminal>Command</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>Comment</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>CommentChar</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>Comprehension</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>DatePart</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>DateTimeLiteral</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>DecimalIntegerLiteral</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>DecimalLongLiteral</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>Declaration</nonterminal>
</xbgf:horizontal>
Expand Down Expand Up @@ -90,9 +69,6 @@
<xbgf:horizontal>
<nonterminal>Kind</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>LAYOUT</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>LanguageAction</nonterminal>
</xbgf:horizontal>
Expand All @@ -105,15 +81,6 @@
<xbgf:horizontal>
<nonterminal>LongLiteral</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>Name</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>NamedRegExp</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>OctalEscapeSequence</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>Parameters</nonterminal>
</xbgf:horizontal>
Expand Down Expand Up @@ -147,36 +114,21 @@
<xbgf:horizontal>
<nonterminal>RascalReservedKeywords</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>RealLiteral</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>Replacement</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>ShellCommand</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>ShortChar</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>Signature</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>SingleQuotedStrChar</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>Statement</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>StrChar</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>Strategy</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>StringCharacter</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>StringLiteral</nonterminal>
</xbgf:horizontal>
Expand All @@ -201,18 +153,9 @@
<xbgf:horizontal>
<nonterminal>Tag</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>TagChar</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>Test</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>TimePartNoTZ</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>TimeZonePart</nonterminal>
</xbgf:horizontal>
<xbgf:horizontal>
<nonterminal>Type</nonterminal>
</xbgf:horizontal>
Expand Down
6 changes: 6 additions & 0 deletions topics/investigation/complexity/Makefile
Expand Up @@ -3,5 +3,11 @@ test:
cp ../../convergence/java/snapshot/*.bgf tests/
ls -1 tests/*.bgf | xargs -n1 ./testperform

check:
bgf2bnf tests/antlr.bgf
./mcc.py tests/antlr.bgf
xbgf horizontalize.xbgf tests/antlr.bgf antlrh.bgf
bgf2bnf antlrh.bgf
./mcc.py antlrh.bgf
clean:
rm -f tests/*.bgf tests/*.out
2 changes: 1 addition & 1 deletion topics/investigation/complexity/hal.py
Expand Up @@ -13,5 +13,5 @@
sys.exit(1)
bgf = BGF.Grammar()
bgf.parse(sys.argv[1])
print metrics.HAL(bgf)
print int(round(metrics.HAEFF(bgf)))
sys.exit(0)

0 comments on commit 59ee138

Please sign in to comment.