]> gitweb.factorcode.org Git - factor.git/blob - extra/shell/parser/parser.factor
f6ffbf03afff962927323c7f5f982c8065a76830
[factor.git] / extra / shell / parser / parser.factor
1 USING: accessors kernel multiline peg peg.ebnf sequences
2 sequences.deep strings ;
3
4 IN: shell.parser
5
6 TUPLE: basic-expr         command  stdin stdout background ;
7 TUPLE: pipeline-expr      commands stdin stdout background ;
8 TUPLE: single-quoted-expr expr ;
9 TUPLE: double-quoted-expr expr ;
10 TUPLE: back-quoted-expr   expr ;
11 TUPLE: glob-expr          expr ;
12 TUPLE: variable-expr      expr ;
13 TUPLE: factor-expr        expr ;
14
15 : ast>basic-expr ( ast -- obj )
16     first4 basic-expr boa ;
17
18 : ast>pipeline-expr ( ast -- obj )
19     pipeline-expr new
20         over [ first ] [ fourth [ first ] map ] [ 4 swap nth ] tri
21         suffix swap prefix >>commands
22         over second >>stdin
23         over 5 swap nth >>stdout
24         swap 6 swap nth >>background ;
25
26 : ast>single-quoted-expr ( ast -- obj )
27     second >string single-quoted-expr boa ;
28
29 : ast>double-quoted-expr ( ast -- obj )
30     second >string double-quoted-expr boa ;
31
32 : ast>back-quoted-expr ( ast -- obj )
33     second >string back-quoted-expr boa ;
34
35 : ast>glob-expr ( ast -- obj )
36     flatten concat glob-expr boa ;
37
38 : ast>variable-expr ( ast -- obj )
39     second variable-expr boa ;
40
41 : ast>factor-expr ( ast -- obj )
42     second >string factor-expr boa ;
43
44 EBNF: expr [=[
45
46 space = " "
47
48 tab   = "\t"
49
50 white = (space | tab)
51
52 _ = (white)* => [[ drop ignore ]]
53
54 sq = "'"
55 dq = '"'
56 bq = "`"
57
58 single-quoted = sq (!(sq) .)* sq => [[ ast>single-quoted-expr ]]
59 double-quoted = dq (!(dq) .)* dq => [[ ast>double-quoted-expr ]]
60 back-quoted   = bq (!(bq) .)* bq => [[ ast>back-quoted-expr   ]]
61
62 factor = "$(" (!(")") .)* ")" => [[ ast>factor-expr ]]
63
64 variable = "$" other => [[ ast>variable-expr ]]
65
66 glob-char = ("*" | "?")
67
68 non-glob-char = !(glob-char | white) .
69
70 glob-beginning-string = (non-glob-char)* => [[ >string ]]
71
72 glob-rest-string = (non-glob-char)+ => [[ >string ]]
73
74 glob = glob-beginning-string glob-char (glob-rest-string | glob-char)* => [[ ast>glob-expr ]]
75
76 other = (!(white | "&" | ">" | ">>" | "<" | "|") .)+ => [[ >string ]]
77
78 element = (single-quoted | double-quoted | back-quoted | factor | variable | glob | other)
79
80 command = (element _)+
81
82 to-file = ">"  _ other => [[ second ]]
83 in-file = "<"  _ other => [[ second ]]
84 ap-file = ">>" _ other => [[ second ]]
85
86 basic = _ command _ (in-file)? _ (to-file | ap-file)? _ ("&")? => [[ ast>basic-expr ]]
87
88 pipeline = _ command _ (in-file)? _ "|" _ (command _ "|" _)* command _ (to-file | ap-file)? _ ("&")? => [[ ast>pipeline-expr ]]
89
90 submission = (pipeline | basic)
91
92 ]=]