1
2
3
4
5
6 [hpp]#include <cpp2cm/cpp2cm/Patch.hpp>
7 [cpp]#include <soulng/lexer/TrivialLexer.hpp>
8 [cpp]#include <soulng/parser/Range.hpp>
9
10 using namespace soulng::lexer;
11
12 parser PatchFileParser
13 {
14 uselexer TrivialLexer;
15 main;
16
17 PatchFile(var std::unique_ptr patchFile) : cpp2cm::PatchFile*
18 ::= (empty{ patchFile.reset(new cpp2cm::PatchFile(lexer.FileName())); } (PatchLine:patch{ patchFile->AddPatch(patch); })+ Newline:nl2*){ return patchFile.release(); }
19 ;
20
21 PatchLine(var std::unique_ptr patch) : cpp2cm::Patch*
22 ::= (FileName:filename ':' LineNumber:lineNumber ':' Patch:p{ patch.reset(p); } Newline:nl){ patch->SetFileName(filename); patch->SetLineNumber(lineNumber); return patch.release(); }
23 ;
24
25 FileName(var Span s) : std::u32string
26 ::= ("[^:\r\n]"{ s = span; } ("[^:\r\n]"{ s.end = span.end; })*){ return lexer.GetMatch(s); }
27 ;
28
29 LineNumber(var Span s) : std::u32string
30 ::= ("[0-9]"{ s = span; } ("[0-9]"{ s.end = span.end; })*){ return lexer.GetMatch(s); }
31 ;
32
33 Patch : cpp2cm::Patch*
34 ::= Insert:ins{ return ins; }
35 | Delete:del{ return del; }
36 | Modify:mod{ return mod; }
37 ;
38
39 Insert : cpp2cm::Patch*
40 ::= ('I' '/' Text:text '/'){ return new cpp2cm::InsertPatch(text); }
41 ;
42
43 Delete : cpp2cm::Patch*
44 ::= ('D'){ return new cpp2cm::DeletePatch(); }
45 ;
46
47 Modify : cpp2cm::Patch*
48 ::= ('M' '/' Text:oldText '/' Text:newText '/'){ return new cpp2cm::ModifyPatch(oldText, newText); }
49 ;
50
51 Text(var Span s) : std::u32string
52 ::= ("[^/\r\n]"{ s = span; } ("[^/\r\n]"{ s.end = span.end; })*){ return lexer.GetMatch(s); }
53 ;
54
55 Newline
56 ::= "\r\n" | '\n' | '\r'
57 ;
58 }