/
TerminalGen.sv
54 lines (47 loc) · 1.86 KB
/
TerminalGen.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
49
50
51
52
53
54
grammar silver:compiler:extension:treegen;
imports silver:core hiding empty, alt;
imports silver:regex;
imports silver:compiler:metatranslation;
imports silver:reflect;
import silver:util:treeset as set; -- needed for freeVars equation
terminal GenArbTerminal_t 'genArbTerminal' lexer classes {KEYWORD, RESERVED};
-- Note that this construct ignores lexical dominates/submits to relationships
-- with other terminals, since we don't have a parser spec/syntax AST to extract
-- that information.
concrete production genArbTerminalNoLocExpr
top::Expr ::= 'genArbTerminal' '(' te::TypeExpr ',' '_' ')'
{
top.unparse = s"genArbTerminal(${te.unparse}, _)";
propagate grammarName, env, flowEnv, freeVars;
local regex::Regex =
case getTypeDcl(te.typerep.typeName, top.env) of
| termDcl(_, r, _, _) :: _ -> r
| _ -> empty()
end;
local genRepeatProb::Float =
case getTypeDcl(te.typerep.typeName, top.env) of
| termDcl(_, _, _, just(grp)) :: _ -> grp
| _ -> 0.75
end;
forwards to
if null(getAttrDcl("silver:regex:genArbMatch", top.env))
then errorExpr([errFromOrigin(top, "Generation of arbitrary terminal values requires import of silver:regex")])
else Silver_Expr {
let genLexeme::RandomGen<String> =
decorate $Expr{translate(reflect(new(regex)))} with {
starProb = $Expr{floatConst(terminal(Float_t, toString(genRepeatProb)))};
altCountIn = 0;
}.genArbMatch
in \ loc::silver:core:Location -> silver:core:map(\ lexeme::String -> terminal($TypeExpr{te}, lexeme, loc), genLexeme)
end
};
}
concrete production genArbTerminalExpr
top::Expr ::= 'genArbTerminal' '(' te::TypeExpr ',' loc::Expr ')'
{
top.unparse = s"genArbTerminal(${te.unparse}, ${loc.unparse})";
forwards to
mkFunctionInvocation(
genArbTerminalNoLocExpr('genArbTerminal', '(', te, ',', '_', ')'),
[loc]);
}