/
OrphanedProduction.sv
49 lines (43 loc) · 1.53 KB
/
OrphanedProduction.sv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
grammar silver:compiler:analysis:warnings:flow;
synthesized attribute warnFwd :: Boolean occurs on CmdArgs;
aspect production endCmdArgs
top::CmdArgs ::= l::[String]
{
top.warnFwd = false;
}
abstract production warnFwdFlag
top::CmdArgs ::= rest::CmdArgs
{
top.warnFwd = true;
forwards to rest;
}
aspect function parseArgs
Either<String Decorated CmdArgs> ::= args::[String]
{
flags <- [
flagSpec(name="--warn-fwd", paramString=nothing(),
help="warn about orphaned productions",
flagParser=flag(warnFwdFlag))];
}
aspect production productionDcl
top::AGDcl ::= 'abstract' 'production' id::Name ns::ProductionSignature body::ProductionBody
{
local ntDefGram :: String =
substring(0, lastIndexOf(":", namedSig.outputElement.typerep.typeName), namedSig.outputElement.typerep.typeName);
local isClosedNt :: Boolean =
case getTypeDclAll(namedSig.outputElement.typerep.typeName, top.env) of
| ntDcl(_, _, _, closed, _) :: _ -> closed
| _ -> false -- default, if the lookup fails
end;
top.errors <-
if null(body.errors ++ ns.errors)
&& top.config.warnFwd
-- If this production does not forward
&& null(body.forwardExpr)
-- AND this is not a closed nonterminal
&& !isClosedNt
-- AND this production is not exported by the nonterminal definition grammar... even including options
&& !isExportedBy(top.grammarName, [ntDefGram], top.compiledGrammars)
then [mwdaWrnFromOrigin(top, "Orphaned production: " ++ id.name ++ " on " ++ namedSig.outputElement.typerep.typeName)]
else [];
}