1
2
3
4
5
6 using Cm.Ast;
7 using LexerFileTokens;
8
9 parser LexerFileParser
10 {
11 uselexer LexerFileLexer;
12
13 using IdentifierParser.Identifier;
14 using IdentifierParser.QualifiedId;
15 using TypeExprParser.TypeExpr;
16 using StatementParser.CompoundStatement;
17
18 main;
19
20 LexerFile(var UniquePtr<soulcm.scmlg.LexerFile> lexerFile, ParsingContext* parsingContext) : soulcm.scmlg.LexerFile*
21 ::= empty{ lexerFile.Reset(new soulcm.scmlg.LexerFile()); }
22 (
23 (Declaration(parsingContext):declaration{ lexerFile->Add(declaration); })*
24 )
25 {
26 return lexerFile.Release();
27 }
28 ;
29
30 Declaration(ParsingContext* parsingContext) : soulcm.scmlg.Declaration*
31 ::= ClassMap:classMapDeclaration{ return classMapDeclaration; }
32 | Usings(parsingContext):usingDeclarations{ return usingDeclarations; }
33 | Tokens:tokensDeclaration{ return tokensDeclaration; }
34 | Keywords:keywordsDeclaration{ return keywordsDeclaration; }
35 | Expressions:expressionsDeclaration{ return expressionsDeclaration; }
36 | Lexer(parsingContext):lexerDeclaration{ return lexerDeclaration; }
37 ;
38
39 ClassMap(var ustring classMapName) : soulcm.scmlg.ClassMap*
40 ::= CLASSMAP ID!{ classMapName = lexer.GetMatch(span); } SEMICOLON!{ return new soulcm.scmlg.ClassMap(classMapName); }
41 ;
42
43 Usings(ParsingContext* ctx, var UniquePtr<soulcm.scmlg.Usings> usings) : soulcm.scmlg.Usings*
44 ::= empty{ usings.Reset(new soulcm.scmlg.Usings()); } UsingDirectives(ctx, usings.Get()):usingDirectives{ return usings.Release(); }
45 ;
46
47 UsingDirectives(ParsingContext* ctx, soulcm.scmlg.Usings* usings)
48 ::= UsingDirective(ctx, usings):usingDirective+
49 ;
50
51 UsingDirective(ParsingContext* ctx, soulcm.scmlg.Usings* usings)
52 ::= UsingAliasDirective(ctx):usingAlias{ usings->AddMember(usingAlias); }
53 | UsingNamespaceDirective(ctx):usingNs{ usings->AddMember(usingNs); }
54 ;
55
56 UsingAliasDirective(ParsingContext* ctx, var Span s) : Node*
57 ::= USING{ s = span; } Identifier(ctx):id ASSIGN QualifiedId(ctx):qid! SEMICOLON!
58 {
59 s.end = span.end;
60 return new AliasNode(s, ctx->ModuleId(), id, qid);
61 }
62 ;
63
64 UsingNamespaceDirective(ParsingContext* ctx, var Span s) : Node*
65 ::= USING{ s = span; } QualifiedId(ctx):ns! SEMICOLON!
66 {
67 s.end = span.end;
68 return new NamespaceImportNode(s, ctx->ModuleId(), ns);
69 }
70 ;
71
72 Tokens(var ustring tokensDeclarationName, var UniquePtr<soulcm.scmlg.Tokens> tokens) : soulcm.scmlg.Tokens*
73 ::= TOKENS ID!{ tokensDeclarationName = lexer.GetMatch(span); } LBRACE!{ tokens.Reset(new soulcm.scmlg.Tokens(tokensDeclarationName)); }
74 (Token:token{ tokens->Add(token); } % COMMA)? RBRACE!
75 {
76 return tokens.Release();
77 }
78 ;
79
80 Token(var ustring tokenName, var ustring tokenInfo) : soulcm.scmlg.Token
81 ::= LPAREN ID!{ tokenName = lexer.GetMatch(span); } COMMA! STRINGLIT!{ tokenInfo = soulcm.scmlg.MakeStrValue(lexer.FileName(), lexer.GetToken(pos)); } RPAREN!
82 {
83 return soulcm.scmlg.Token(tokenName, ToUtf8(tokenInfo));
84 }
85 ;
86
87 Keywords(var ustring keywordsDeclarationName, var UniquePtr<soulcm.scmlg.Keywords> keywords) : soulcm.scmlg.Keywords*
88 ::= KEYWORDS ID!{ keywordsDeclarationName = lexer.GetMatch(span); } LBRACE!{ keywords.Reset(new soulcm.scmlg.Keywords(keywordsDeclarationName)); }
89 (Keyword:keyword{ keywords->Add(keyword); } % COMMA)? RBRACE!
90 {
91 return keywords.Release();
92 }
93 ;
94
95 Keyword(var ustring kw, var ustring tokenName) : soulcm.scmlg.Keyword*
96 ::= LPAREN STRINGLIT!{ kw = soulcm.scmlg.MakeStrValue(lexer.FileName(), lexer.GetToken(pos)); } COMMA! ID!{ tokenName = lexer.GetMatch(span); } RPAREN!
97 {
98 return new soulcm.scmlg.Keyword(kw, tokenName);
99 }
100 ;
101
102 Expressions(var int index, var UniquePtr<soulcm.scmlg.Expressions> expressions) : soulcm.scmlg.Expressions*
103 ::= EXPRESSIONS{ index = 0; expressions.Reset(new soulcm.scmlg.Expressions()); } LBRACE!
104 (Expression(index):expr{ expressions->Add(expr); index = index + 1; })* RBRACE!
105 {
106 return expressions.Release();
107 }
108 ;
109
110 Expression(int index, var ustring exprName, var int line) : soulcm.scmlg.Expression*
111 ::= ID{ exprName = lexer.GetMatch(span); } ASSIGN ExprString:exprValue!{ line = lexer.GetToken(pos).line; } SEMICOLON!
112 {
113 return new soulcm.scmlg.Expression(index, exprName, exprValue, line);
114 }
115 ;
116
117 ExprString : ustring
118 ::= STRINGLIT{ return soulcm.scmlg.MakeExprStringValue(lexer.FileName(), lexer.GetToken(pos)); }
119 ;
120
121 Lexer(ParsingContext* parsingContext, var ustring lexerDeclarationName, var UniquePtr<soulcm.scmlg.Lexer> currentLexer) : soulcm.scmlg.Lexer*
122 ::= LEXER ID!{ lexerDeclarationName = lexer.GetMatch(span); } LBRACE!{ currentLexer.Reset(new soulcm.scmlg.Lexer(u"", lexerDeclarationName)); }
123 (LexerClause(currentLexer.Get(), parsingContext):lexerClause)* RBRACE!
124 {
125 return currentLexer.Release();
126 }
127 ;
128
129 LexerClause(soulcm.scmlg.Lexer* currentLexer, ParsingContext* parsingContext, var int line)
130 ::= (ExprString:expr{ line = lexer.GetToken(pos).line; } Action:action CompoundStatement(parsingContext):stmt!){ currentLexer->AddStatement(new soulcm.scmlg.LexerStatement(expr, stmt, action, line)); }
131 | Variables(currentLexer, parsingContext):variables
132 | Actions(currentLexer, parsingContext):actions
133 ;
134
135 Variables(soulcm.scmlg.Lexer* currentLexer, ParsingContext* parsingContext)
136 ::= VARIABLES LBRACE! (Variable(parsingContext):variable{ currentLexer->AddVariable(variable); })* RBRACE!
137 ;
138
139 Variable(ParsingContext* parsingContext, var ustring name) : soulcm.scmlg.Variable*
140 ::= TypeExpr(parsingContext):type ID{ name = lexer.GetMatch(span); } SEMICOLON{ return new soulcm.scmlg.Variable(type, name); }
141 ;
142
143 Actions(soulcm.scmlg.Lexer* currentLexer, ParsingContext* parsingContext)
144 ::= ACTIONS LBRACE! ((Action:action{ pass = action != -1; } ASSIGN CompoundStatement(parsingContext):stmt!){ currentLexer->AddAction(new soulcm.scmlg.Action(action, stmt)); })* RBRACE!
145 ;
146
147 Action(var int actionId) : int
148 ::= (DOLLAR LPAREN! INTLIT!{ actionId = soulcm.scmlg.MakeActionIntValue(lexer.FileName(), lexer.GetToken(pos)); } RPAREN!){ return actionId; }
149 | empty{ return -1; }
150 ;
151
152 ruleinfo
153 {
154 (LexerFile, "lexer file"), (Declaration, "lexer file declaration"), (ClassMap, "class map declaration"), (Tokens, "tokens declaration"), (Token, "token declaration"),
155 (Keywords, "keywords declaration"), (Keyword, "keyword declaration"), (Expressions, "regular expressions declaration"),
156 (Expression, "regular expression declaration"), (ExprString, "regular expression string"), (Lexer, "lexer declaration"), (LexerClause, "lexer clause"),
157 (Variables, "variables"), (Variable, "variable"), (Actions, "actions"), (Action, "action identifier")
158 }
159 }