1
2
3
4
5
6 [hpp]#include <sngcm/cmparser/ParserApi.hpp>
7 [hpp]#include <vector>
8 [hpp]#include <string>
9 [cpp]#include <soulng/lexer/TrivialLexer.hpp>
10 [cpp]#include <soulng/parser/Range.hpp>
11
12 using namespace soulng::lexer;
13
14 parser api(SNGCM_PARSER_API) CommandLineParser
15 {
16 uselexer TrivialLexer;
17 main;
18
19 CommandLine(var std::vector value) : std::vector
20 ::= (Spaces:spc1? Argument:first{ value.push_back(first); } (Spaces:spc2 Argument:next{ value.push_back(next); })* Spaces:spc3? '\n'){ return value; }
21 ;
22
23 Spaces
24 ::= "[\t ]"+
25 ;
26
27 Argument(var std::string value) : std::string
28 ::= ((ArgElement:element{ value.append(element); })+){ return value; }
29 ;
30
31 ArgElement(var std::string value) : std::string
32 ::= OddBackslashesAndLiteralQuotationMark:o{ return o; }
33 | EvenBackslashesAndQuotationMark:s{ value.append(s); } (StringChar:sc{ value.append(sc); })* EvenBackslashesAndQuotationMark:e{ value.append(e); return value; }
34 | "[^\t\n\r ]"{ value.append(ToUtf8(lexer.GetMatch(span))); return value; }
35 ;
36
37 OddBackslashesAndLiteralQuotationMark(var Span s, var std::string value) : std::string
38 ::= "[\\]"{ s = span; } "[\\]"* '"'
39 {
40 s.end = span.end;
41 std::u32string bs = lexer.GetMatch(s);
42 int n = bs.length() - 1;
43 pass = n % 2 == 1;
44 if (pass)
45 {
46 value = std::string(n / 2, '\\');
47 value.append(1, '"');
48 return value;
49 }
50 }
51 ;
52
53 EvenBackslashesAndQuotationMark(var Span s, var std::string value) : std::string
54 ::= empty{ s = span; } "[\\]"* '"'
55 {
56 s.end = span.end;
57 std::u32string bs = lexer.GetMatch(s);
58 int n = bs.length() - 1;
59 pass = n % 2 == 0;
60 if (pass)
61 {
62 value = std::string(n / 2, '\\');
63 return value;
64 }
65 }
66 ;
67
68 StringChar(var Span s) : std::string
69 ::= OddBackslashesAndLiteralQuotationMark:o{ return o; }
70 | (("[^\n\r]"{ s = span; }) - EvenBackslashesAndQuotationMark:m){ return ToUtf8(lexer.GetMatch(s)); }
71 ;
72 }