Blame view

code/biflang/BIFLang.jl 4.46 KB
3e0f9b8a   Francisco Coelho   back to work?
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
module BIFLang

export parse_bif, debug_bif, fmt,
    NetworkKW,
    VariableKW,
    ProbabilityKW,
    PropertyKW,
    VariabletypeKW,
    DiscreteKW,
    DefaultvalueKW,
    TablevaluesKW,
    Property,
    Properties,
    Variable,
    Parents,
    Values,
    Key,
    ProbabilityDeclaration,
    VariableDeclaration,
    Distribution,
    DefaultEntry,
    Entry,
    Discrete,
    Network,
    Unit

using ParserCombinator

abstract type Node end;

Base.:(==)(a::Node, b::Node) = (typeof(a) == typeof(b)) && (a.args == b.args)
function Base.print(io::IO, n::Node)
    show_type = n |> typeof |> string
    Base.print(io, show_type)
    if isa(n.args, AbstractArray) && length(n.args) > 0
        show_args = join(n.args .|> ni -> "$ni", ",")
        Base.print(io, "($show_args)")
    end
end
        
macro grammar(lang)
    return quote
        struct $lang <: Node args end;
    end
end


abstract type Keyword end;
Base.:(==)(a::Keyword, b::Keyword) = (typeof(a) == typeof(b))
fmt(n::Keyword) =  "$(n |> typeof |> string)"
macro keyword(lang)
    return quote
        struct $lang <: Keyword end;
    end
end

@keyword NetworkKW
@keyword VariableKW
@keyword ProbabilityKW
@keyword PropertyKW
@keyword VariabletypeKW
@keyword DiscreteKW
@keyword DefaultvalueKW
@keyword TablevaluesKW

@grammar Property
@grammar Properties
@grammar Variable
@grammar Parents
@grammar Values
@grammar Key

@grammar ProbabilityDeclaration
@grammar VariableDeclaration

@grammar Distribution
@grammar DefaultEntry
@grammar Entry

@grammar Discrete
@grammar Network
@grammar Compilation
@grammar Unit

@with_names begin
spc = Drop(Star(Space()))
@with_pre spc begin
@with_post spc begin
    
word    = p"[a-zA-Z]([a-zA-Z0-9_-])*"

decimal = PInt64()
floating_point  = PFloat64()

network_kw      = E"network"     > NetworkKW            
variable_kw     = E"variable"    > VariableKW            
probability_kw  = E"probability" > ProbabilityKW                
property_kw     = E"property"    > PropertyKW            
variabletype_kw = E"type"        > VariabletypeKW        
discrete_kw     = E"discrete"    > DiscreteKW            
defaultvalue_kw = E"default"     > DefaultvalueKW            
tablevalues_kw  = E"table"       > TablevaluesKW        

property = Drop(property_kw) + spc + p"[^;]+" + E";" |> Property

floatingpoint_list          = PlusList(floating_point, E",")
probability_table           = Drop(tablevalues_kw)  + floatingpoint_list + spc + E";" |> Distribution
probability_defaultentry    = Drop(defaultvalue_kw) + floatingpoint_list + spc + E";" |> DefaultEntry

probability_value   = word
probability_values  = E"(" + spc + PlusList(probability_value, spc + E","+spc) + spc + E")"
probability_entry   = (probability_values  |> Key) + (floatingpoint_list |>  Distribution) + spc + E";" |> Entry

probability_content = E"{" + spc +
    Star( property | probability_defaultentry | probability_entry | probability_table ) + spc +
    E"}"

probability_variable    = word |> Variable
probability_variables   = E"(" + spc + probability_variable + Opt(E"|" + PlusList(probability_variable, E",") |> Parents) + spc + E")"
probability_declaration = Drop(probability_kw) + probability_variables + probability_content |> ProbabilityDeclaration

variable_values = PlusList(probability_value, spc + E"," + spc)

variable_discrete   = Drop(variabletype_kw + discrete_kw) + 
    E"[" + decimal + E"]" + spc + E"{" + spc + (variable_values |> Values) + spc + E"}" |> Discrete
variable_content    = E"{" + Star((property | variable_discrete) + spc + E";" + spc) + E"}"
variable_declaration= Drop(variable_kw) + probability_variable + variable_content |> VariableDeclaration

network_content     = E"{" + spc + Star(property) + spc + E"}" |> Properties
network_declaration = Drop(network_kw) + word + network_content |> Network

compilation_unit    = network_declaration + Star(variable_declaration | probability_declaration) |> Unit

bif_grammar = compilation_unit + Eos()
end
end
end


parse_bif(source::String) = parse_one(source, bif_grammar)[1]

function debug_bif(source::String, show_trace=false)
    debug, task = make(Debug, source, bif_grammar; delegate=NoCache)
    try
        once(task)
        expr = parse_bif(source)
        println("---\n\"$source\"\n\tparses to\n$(expr)\n---")
    catch #_::ParserException
        p = debug.max_iter
        println("Error parsing after \"$(source[max(1,p-20):p - 1])\" and before \"$(source[p:p+20])\".\n")

        if show_trace
            parse_dbg(source, Trace(grammar=bif_grammar))
        end
    end
end
end