aboutsummaryrefslogtreecommitdiff
path: root/steuermann/specfile.exy
blob: 7cdf1f3543ff750fd9ac98a550af957baa467664 (plain) (blame)
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

# Parse a Steuermann Spec file
#
# This is an exyapps grammer in specfile.exy

%%
parser specfile:
    ignore: "[ \r\t\n]+"
    ignore: "#.*\n"

    token END: "$"
    token TABLE: "TABLE"
    token HOST : "HOST"
    token CMD: "CMD"
    token OPT: "OPT"
    token AFTER: "AFTER"
    token name: "[a-zA-Z0-9_.-]+"
    token STAR: "\*"
    token cmdname: "[a-zA-Z0-9_.-]+"
    token tablename: "[a-zA-Z0-9_.-]+"
    token wildname: "[*?a-zA-Z0-9_.-]+"
    token RUN: "RUN"
    token LOCAL: "LOCAL"
    token string: '"[^"]*"'
    token SLASH: "/"
    token COLON: ":"

    rule start: table_list END {{ return table_list }}

    rule table_list:  table_section [ table_list ]

    rule table_section:
        TABLE tablename {{ table_name = tablename }}
		HOST {{ hostlist = [ ] }}
		( 
			name {{ hostlist.append(name) }} 
		)+  
	        command_list  
		# command_list is a list of (command, pos) where command is the text from the file and pos is the location in the file
                {{ self.data.add_command_list( table_name, hostlist, command_list )  }}

    rule command_list:  
	# one or more commands, appended together into a list
        {{ cmlist = [ ] }} 
        command {{ cmlist.append( command ) }} 
        [ 
		command_list {{ cmlist += command_list }} 
	] 
        {{ return cmlist }} 
   	| {{ return [ ] }}

    rule command: 
	# a single command, including any number of AFTER clauses
        CMD  {{ cmd_pos = self._scanner.get_pos() }} 
    	    cmdname  {{ cmd_name=cmdname; script=cmdname; x_after_clause = [ ] }} 
            [ RUN string {{ script = string[1:-1]; script_type='r' }} 
		| LOCAL string {{ script = string[1:-1]; script_type='l' }} 
	    ]
            ( {{ after_pos = self._scanner.get_pos() }} 
		AFTER optword after_spec {{ x_after_clause.append( (after_spec, optword, after_pos) ) }}
	    )*
            {{ return ( cmd_name, script, script_type, x_after_clause, cmd_pos ) }}  

    # in the AFTER clause, you can say OPT to mean the node is optional (not an error if it does not exist)
    rule optword:
        OPT {{ return 0 }}
        | {{ return 1 }}

    rule after_spec: 
        wildname {{ rval = wildname }} 
        [ COLON  wildname {{ rval = rval + ':' + wildname }} ]
        [ SLASH  wildname {{ rval = rval + '/' + wildname }} ]
        {{ return rval }}

%%