📄 instr.g
字号:
options {
language = "Sather";
}
class INSTR_PARSER extends Parser;
options {
buildAST = true;
k=2;
}
tokens {
CALL; // define imaginary token CALL
}
slist
: ( stat )+
;
stat: LBRACE^ (stat)+ RBRACE
| "if"^ expr "then" stat ("else" stat)?
| ID ASSIGN^ expr SEMI
| call
;
expr
: mexpr (PLUS^ mexpr)*
;
mexpr
: atom (STAR^ atom)*
;
atom: INT
| ID
;
call: ID LPAREN (expr)? RPAREN SEMI
{@call := @(@[CALL,"CALL"], @call);}
;
class INSTR_LEXER extends Lexer;
options {
charVocabulary = '\3'..'\377';
}
WS : (' '
| '\t'
| ('\n'|'\r'('\n')?) {newline;}
)+
;
// Single-line comments
SL_COMMENT
: "//"
(~('\n'|'\r'))* ('\n'|'\r'('\n')?)
{newline;}
;
LBRACE: '{'
;
RBRACE: '}'
;
LPAREN: '('
;
RPAREN: ')'
;
STAR: '*'
;
PLUS: '+'
;
SEMI: ';'
;
ASSIGN
: '='
;
protected
DIGIT
: '0'..'9'
;
INT : (DIGIT)+
;
ID : ('a'..'z')+
;
class INSTR_TREE_WALKER extends TreeParser;
{
-- MAIN does not do well with a shared attribute, it seems, so
-- I put it here.
private attr filter : ANTLR_TOKEN_STREAM_HIDDEN_TOKEN_FILTER;
create ( f : ANTLR_TOKEN_STREAM_HIDDEN_TOKEN_FILTER ) : SAME is
res ::= SAME::create;
res.filter := f;
return res;
end;
print ( s : STR ) is
OUT::create + s;
end;
-- walk list of hidden tokens in order, printing them out
dump_hidden( t : ANTLR_COMMON_HIDDEN_STREAM_TOKEN ) is
loop while!( ~void(t) );
print(t.text);
t := filter.hidden_after(t);
end;
end;
pr( p : ANTLR_COMMON_AST_WITH_HIDDEN_TOKENS ) is
print( p.text );
dump_hidden( p.hidden_after );
end;
}
slist
: {dump_hidden( filter.first_hidden_token );}
(stat)+
;
stat: #(LBRACE {pr(@LBRACE);} (stat)+ RBRACE {pr(@RBRACE);})
| #(i:"if" {pr(i);} expr t:"then" {pr(t);} stat (e:"else" {pr(e);} stat)?)
| #(ASSIGN ID {pr(@ID); pr(@ASSIGN);} expr SEMI {pr(@SEMI);} )
| call
;
expr
: #(PLUS expr {pr(@PLUS);} expr)
| #(STAR expr {pr(@STAR);} expr)
| INT {pr(@INT);}
| ID {pr(@ID);}
;
call: {
-- add instrumentation about call; manually call rule
callDumpInstrumentation(@call);
}
#(CALL ID {pr(@ID);}
LPAREN {pr(@LPAREN);} (expr)? RPAREN {pr(@RPAREN);}
SEMI
{
-- print SEMI manually; need '}' between it and whitespace
print(@SEMI.text);
print("}"); -- close {...} of instrumentation
dump_hidden( (@SEMI).hidden_after );
}
)
;
/* Dump instrumentation for a call statement.
* The reference to rule expr prints out the arg
* and then at the end of this rule, we close the
* generated called to dbg.invoke().
*/
callDumpInstrumentation
: #(CALL id:ID
{ print("{dbg.invoke(\"" + id.text + "\", \"" ); }
LPAREN (e:expr)? RPAREN SEMI
{ print("\"); "); }
)
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -