1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
header {
#include "Main.hpp"
#include <string>
#include <iostream>
}
options {
language = Cpp;
}
class PParser extends Parser;
{
public:
void traceOut(ANTLR_USE_NAMESPACE(std)string rname) /*throws TokenStreamException*/ {
ANTLR_USE_NAMESPACE(std)cout << "exit " << rname << "; LT(1)=" << LT(1) << ANTLR_USE_NAMESPACE(std)endl;
}
void traceIn(ANTLR_USE_NAMESPACE(std)string rname) /*throws TokenStreamException*/ {
ANTLR_USE_NAMESPACE(std)cout << "enter " << rname << "; LT(1)=" << LT(1) << ANTLR_USE_NAMESPACE(std)endl;
}
/*
public void consume() throws IOException {
try {
System.out.println(LT(1));
}
catch (IOException ignore) {}
super.consume();
}
*/
}
startRule
: ( decl )+
;
decl: INT a:ID {ANTLR_USE_NAMESPACE(std)cout << "decl " << a->getText() << ANTLR_USE_NAMESPACE(std)endl;}
( COMMA b:ID {ANTLR_USE_NAMESPACE(std)cout << "decl " << b->getText() << ANTLR_USE_NAMESPACE(std)endl;} )*
SEMI
;
{
#include <fstream>
#include "PParser.hpp"
}
class PLexer extends Lexer;
options {
charVocabulary = '\3'..'\377';
k=2;
}
tokens {
INT="int";
}
{
public:
void uponEOF() /*throws TokenStreamException, CharStreamException*/ {
if ( selector.getCurrentStream() != mainLexer ) {
// don't allow EOF until main lexer. Force the
// selector to retry for another token.
selector.pop(); // return to old lexer/stream
selector.retry();
}
else {
ANTLR_USE_NAMESPACE(std)cout << "Hit EOF of main file" << ANTLR_USE_NAMESPACE(std)endl;
}
}
}
SEMI: ';'
;
COMMA
: ','
;
ID
: ('a'..'z')+
;
INCLUDE
: "#include" (WS_)? f:STRING
{
ANTLR_USING_NAMESPACE(std)
// create lexer to handle include
string name = f->getText();
ifstream* input = new ifstream(name.c_str());
if (!*input) {
cerr << "cannot find file " << name << endl;
}
PLexer* sublexer = new PLexer(*input);
// make sure errors are reported in right file
sublexer->setFilename(name);
parser->setFilename(name);
// you can't just call nextToken of sublexer
// because you need a stream of tokens to
// head to the parser. The only way is
// to blast out of this lexer and reenter
// the nextToken of the sublexer instance
// of this class.
selector.push(sublexer);
// ignore this as whitespace; ask selector to try
// to get another token. It will call nextToken()
// of the new instance of this lexer.
selector.retry(); // throws TokenStreamRetryException
}
;
STRING
: '"'! ( ~'"' )* '"'!
;
WS_ : ( ' '
| '\t'
| '\f'
// handle newlines
| ( options {generateAmbigWarnings=false;}
: "\r\n" // Evil DOS
| '\r' // Macintosh
| '\n' // Unix (the right way)
)
{ newline(); }
)+
{ $setType(ANTLR_USE_NAMESPACE(antlr)Token::SKIP); }
;
|