SMLメッセージのパーサーを書いています。入力:多くのSMLメッセージを含むファイル。Ouput:識別された要素を持つメッセージのキュー。これは私のコードです:
grammar SML;
options {language = Java;}
@header {
package SECSParser;
import SECSParser.SMLLexer;
}
@lexer::header {
package SECSParser;
}
@parser::members {
public static void main(String[] args) throws Exception {
String file = "C:\\Messages.sml";
SMLLexer lexer = new SMLLexer(new ANTLRFileStream(file));
SMLParser parser = new SMLParser(new CommonTokenStream(lexer));
parser.program();
}
}
@lexer::members {
public static String place = "end";
public static void setPlace(String text) { SMLLexer.place = text; }
public static String getPlace() {return SMLLexer.place;}
public static boolean placeIsType() {
return (SMLLexer.place.equals("wb")
| SMLLexer.place.equals("value")
| SMLLexer.place.equals("type"));
}
public static boolean placeIsStreamFunction() {
return (SMLLexer.place.equals("sf") | SMLLexer.place.equals("name"));
}
public static boolean placeIsWaitBit() {
return (SMLLexer.place.equals("sf") | SMLLexer.place.equals("wb"));
}
public boolean ahead() {
if ((input.LA(-2) == 'S') || (input.LA(-2) == 's')) {
return false;
}
return true;
}
}
program:(message)* EOF;
message:{System.out.println("MESSAGE : \n");}
{SMLLexer.setPlace("name");}
name ws* ':' ws* {SMLLexer.setPlace("sf");} str_func
(ws+ {SMLLexer.setPlace("wb");} waitbit)? (ws+ item)? '.'
ws* {SMLLexer.setPlace("end");};
name:LETTER(LETTER| NUMBER| '_')* {System.out.println("NAME : " + $text + "\n");};
fragment STR:~('\'' | '\"');
NUMBER:'0'..'9';
LETTER:(('A'..'Z') | ('a'..'z'));
str_func: (('S' | 's') stream ('F' | 'f') function);
stream: NUMBER+ {System.out.println("STREAM : " + $text + "\n");};
function: NUMBER+ {System.out.println("FUNCTION : " + $text + "\n");};
waitbit: {SMLLexer.placeIsWaitBit()}?=>('W' | 'w') {
System.out.println("WAITBIT : " + $text + "\n");
};
item:{System.out.println("ITEM : \n");} ws* SITEM ws* {SMLLexer.setPlace("type");}
TYPE ( (ws* '[' number_item ']')? ws+ {SMLLexer.setPlace("value");}value)?
ws* EITEM ws* COMMENT? ws*;
SITEM: '<' {SMLLexer.setPlace("type");};
EITEM: '>';
TYPE:{SMLLexer.placeIsType()}?=>( 'A' | 'a' | 'L'| 'l'| 'BINARY'| 'binary'| 'BOOLEAN'| 'boolean'| 'JIS'| 'jis'| 'I8'| 'i8' | 'I1'| 'i1'| 'I2'| 'i2' | 'I4'| 'i4'| 'F4'| 'f4'| 'F8'| 'f8'| 'U8'| 'u8' | 'U1'| 'u1'| 'U2' | 'u2'| 'U4'| 'u4' ){System.out.println("TYPE : " + $text + "\n");};
number_item: NUMBER+ {System.out.println("NUMBER ITEM : " + $text + "\n");};
value:(item ws*)+| (string ws*)+| ((LETTER| NUMBER)ws*)+;
COMMENT:('/*' (options {greedy=false;}: .)* '*/') {$channel = HIDDEN;};
string:('\'' STR? '\'')| ('\"' STR? '\"') {System.out.println("VALUE : " + $text + "\n");};
ANY:.;
ws:(' '| '\t'| '\r'| '\n'| '\f');
これは私のファイル「Message.sml」です
Are_You_There1l : S1F4 W.
On_Line_Data:S1F4 W
<L[2]
<U4 13>
<U4 7>
>.
W1Are_You_There: S1F4 W.
そして結果は次のとおりです。
MESSAGE :
NAME : Are_You_There1l
STREAM : 1
FUNCTION : 4
WAITBIT : W
MESSAGE :
NAME : On_Line_Data
STREAM : 1
FUNCTION : 4
WAITBIT : W
ITEM :
MESSAGE :
NAME : L
TYPE : U4
TYPE : U4
MESSAGE :
NAME : Are_You_There
STREAM : 1
FUNCTION : 4
WAITBIT : W
**C:\Messages.sml line 4:1 mismatched input 'L' expecting TYPE
C:\Messages.sml line 4:2 mismatched input '[' expecting ':'**
プログラムがTYPE:'L'を認識できない理由がわかりません。TYPE'U4'で試してみましたが、動作します。