jFuzzyLogic/fcl/Fcl.g

236 lines
9.0 KiB
Plaintext

//-----------------------------------------------------------------------------
//
// FCL (IEC 1131) lexer & parser implementation
// using antlr (see http://www.antlr.org/)
//
// Pablo Cingolani
//
// Notes: Adapted to ANTLR 3.1 (Sep 2008)
//-----------------------------------------------------------------------------
grammar Fcl;
options {
// We're going to output an AST.
output = AST;
}
// Tokens (reserved words)
tokens {
POINT;
FCL;
VALUE_REAL;
VALUE_ID;
}
@lexer::header {
package net.sourceforge.jFuzzyLogic.fcl;
}
@header {
package net.sourceforge.jFuzzyLogic.fcl;
}
ABS : ('a'|'A')('b'|'B')('s'|'S');
ACCU : ('a'|'A')('c'|'C')('c'|'C')('u'|'U');
ACT : ('a'|'A')('c'|'C')('t'|'T');
AND : ('a'|'A')('n'|'N')('d'|'D');
ASUM : ('a'|'A')('s'|'S')('u'|'U')('m'|'M');
BDIF : ('b'|'B')('d'|'D')('i'|'I')('f'|'F');
BSUM : ('b'|'B')('s'|'S')('u'|'U')('m'|'M');
COA : ('c'|'C')('o'|'O')('a'|'A');
COSINE : ('c'|'C')('o'|'O')('s'|'S')('i'|'I')('n'|'N')('e'|'E');
COG : ('c'|'C')('o'|'O')('g'|'G');
COGS : ('c'|'C')('o'|'O')('g'|'G')('s'|'S');
COGF : ('c'|'C')('o'|'O')('g'|'G')('f'|'F');
COS : ('c'|'C')('o'|'O')('s'|'S');
DEFAULT : ('d'|'D')('e'|'E')('f'|'F')('a'|'A')('u'|'U')('l'|'L')('t'|'T');
DEFUZZIFY : ('d'|'D')('e'|'E')('f'|'F')('u'|'U')('z'|'Z')('z'|'Z')('i'|'I')('f'|'F')('y'|'Y');
DMAX : ('d'|'D')('m'|'M')('a'|'A')('x'|'X');
DMIN : ('d'|'D')('m'|'M')('i'|'I')('n'|'N');
DSIGM : ('d'|'D')('s'|'S')('i'|'I')('g'|'G')('m'|'M');
EINSTEIN : ('e'|'E')('i'|'I')('n'|'N')('s'|'S')('t'|'T')('e'|'E')('i'|'I')('n'|'N');
END_DEFUZZIFY : ('e'|'E')('n'|'N')('d'|'D')'_'('d'|'D')('e'|'E')('f'|'F')('u'|'U')('z'|'Z')('z'|'Z')('i'|'I')('f'|'F')('y'|'Y');
END_FUNCTION_BLOCK : ('e'|'E')('n'|'N')('d'|'D')'_'('f'|'F')('u'|'U')('n'|'N')('c'|'C')('t'|'T')('i'|'I')('o'|'O')('n'|'N')'_'('b'|'B')('l'|'L')('o'|'O')('c'|'C')('k'|'K');
END_FUZZIFY : ('e'|'E')('n'|'N')('d'|'D')'_'('f'|'F')('u'|'U')('z'|'Z')('z'|'Z')('i'|'I')('f'|'F')('y'|'Y');
END_RULEBLOCK : ('e'|'E')('n'|'N')('d'|'D')'_'('r'|'R')('u'|'U')('l'|'L')('e'|'E')('b'|'B')('l'|'L')('o'|'O')('c'|'C')('k'|'K');
END_VAR : ('e'|'E')('n'|'N')('d'|'D')'_'('v'|'V')('a'|'A')('r'|'R');
EXP : ('e'|'E')('x'|'X')('p'|'P');
HAMACHER : ('h'|'H')('a'|'A')('m'|'M')('a'|'A')('c'|'C')('h'|'H')('e'|'E')('r'|'R');
FUNCTION : ('f'|'F')('u'|'U')('n'|'N')('c'|'C')('t'|'T')('i'|'I')('o'|'O')('n'|'N');
GAUSS : ('g'|'G')('a'|'A')('u'|'U')('s'|'S')('s'|'S');
GAUSS2 : ('g'|'G')('a'|'A')('u'|'U')('s'|'S')('s'|'S')'2';
GBELL : ('g'|'G')('b'|'B')('e'|'E')('l'|'L')('l'|'L');
FUNCTION_BLOCK : ('f'|'F')('u'|'U')('n'|'N')('c'|'C')('t'|'T')('i'|'I')('o'|'O')('n'|'N')'_'('b'|'B')('l'|'L')('o'|'O')('c'|'C')('k'|'K');
FUZZIFY : ('f'|'F')('u'|'U')('z'|'Z')('z'|'Z')('i'|'I')('f'|'F')('y'|'Y');
IF : ('i'|'I')('f'|'F');
IS : ('i'|'I')('s'|'S');
LM : ('l'|'L')('m'|'M');
LN : ('l'|'L')('n'|'N');
LOG : ('l'|'L')('o'|'O')('g'|'G');
MAX : ('m'|'M')('a'|'A')('x'|'X');
METHOD : ('m'|'M')('e'|'E')('t'|'T')('h'|'H')('o'|'O')('d'|'D');
MIN : ('m'|'M')('i'|'I')('n'|'N');
NIPMIN : ('n'|'N')('i'|'I')('p'|'P')('m'|'M')('i'|'I')('n'|'N');
NIPMAX : ('n'|'N')('i'|'I')('p'|'P')('m'|'M')('a'|'A')('x'|'X');
MM : ('m'|'M')('m'|'M');
NC : ('n'|'N')('c'|'C');
NOT : ('n'|'N')('o'|'O')('t'|'T');
NSUM : ('n'|'N')('s'|'S')('u'|'U')('m'|'M');
OR : ('o'|'O')('r'|'R');
PROBOR : ('p'|'P')('r'|'R')('o'|'O')('b'|'B')('o'|'O')('r'|'R');
PROD : ('p'|'P')('r'|'R')('o'|'O')('d'|'D');
RANGE : ('r'|'R')('a'|'A')('n'|'N')('g'|'G')('e'|'E');
RM : ('r'|'R')('m'|'M');
RULE : ('r'|'R')('u'|'U')('l'|'L')('e'|'E');
RULEBLOCK : ('r'|'R')('u'|'U')('l'|'L')('e'|'E')('b'|'B')('l'|'L')('o'|'O')('c'|'C')('k'|'K');
SIGM : ('s'|'S')('i'|'I')('g'|'G')('m'|'M');
SIN : ('s'|'S')('i'|'I')('n'|'N');
SINGLETONS : ('s'|'S')('i'|'I')('n'|'N')('g'|'G')('l'|'L')('e'|'E')('t'|'T')('o'|'O')('n'|'N')('s'|'S');
SUM : ('s'|'S')('u'|'U')('m'|'M');
TAN : ('t'|'T')('a'|'A')('n'|'N');
TERM : ('t'|'T')('e'|'E')('r'|'R')('m'|'M');
THEN : ('t'|'T')('h'|'H')('e'|'E')('n'|'N');
TRAPE : ('t'|'T')('r'|'R')('a'|'A')('p'|'P')('e'|'E');
TRIAN : ('t'|'T')('r'|'R')('i'|'I')('a'|'A')('n'|'N');
TYPE_REAL : ('r'|'R')('e'|'E')('a'|'A')('l'|'L');
VAR_INPUT : ('v'|'V')('a'|'A')('r'|'R')'_'('i'|'I')('n'|'N')('p'|'P')('u'|'U')('t'|'T');
VAR_OUTPUT : ('v'|'V')('a'|'A')('r'|'R')'_'('o'|'O')('u'|'U')('t'|'T')('p'|'P')('u'|'U')('t'|'T');
WITH : ('w'|'W')('i'|'I')('t'|'T')('h'|'H');
//-----------------------------------------------------------------------------
// Lexer
//-----------------------------------------------------------------------------
// Send runs of space and tab characters to the hidden channel.
WS: (' ' | '\t')+ { $channel = HIDDEN; };
// Treat runs of newline characters as a single NEWLINE token.
// On some platforms, newlines are represented by a \n character.
// On others they are represented by a \r and a \n character.
NEWLINE: ('\r'? '\n')+ { $channel=HIDDEN; };
// Common symbols
ASSIGN_OPERATOR : ':' '=';
COLON : ':';
COMMA : ',';
DOT : '.';
DOTS : '..';
HAT : '^' ;
LEFT_CURLY : '{';
LEFT_PARENTHESIS: '(';
MINUS : '-' ;
PERCENT : '%' ;
PLUS : '+' ;
RIGHT_CURLY : '}';
RIGHT_PARENTHESIS: ')' ;
SEMICOLON : ';' ;
SLASH : '/' ;
STAR : '*' ;
// A number is a set of digits
fragment NUMBER : (DIGIT)+;
// A DIGIT
fragment DIGIT : '0'..'9' ;
// A letter
fragment LETTER: LOWER | UPPER;
fragment LOWER: 'a'..'z';
fragment UPPER: 'A'..'Z';
// Letter or digit
fragment ALPHANUM : LETTER | DIGIT;
// Real number (float/double) without any sign
REAL : (PLUS|MINUS)? NUMBER ( '.' NUMBER )? (('e'|'E') (PLUS|MINUS)? NUMBER)? ;
// FCL style comments
COMMENT options { greedy = false; }
: '(*' .* '*)' NEWLINE? { $channel=HIDDEN; };
// 'C' style comments
COMMENT_C options { greedy = false; }
: '/*' .* '*/' NEWLINE? { $channel=HIDDEN; };
// 'C' style single line comments
COMMENT_SL : '//' ~('\r' | '\n')* NEWLINE { $channel=HIDDEN; };
// An identifier.
ID : LETTER (ALPHANUM | '_')*;
//-----------------------------------------------------------------------------
// Parser
//-----------------------------------------------------------------------------
// FCL file may contain several funcion blocks
main : f=fcl -> ^(FCL $f);
fcl : (function_block)+;
// Function block
function_block : FUNCTION_BLOCK^ (ID)? (declaration)* END_FUNCTION_BLOCK!;
declaration : var_input | var_output | fuzzify_block | defuzzify_block | rule_block;
// Variables input and output
var_input : VAR_INPUT^ (var_def)* END_VAR!;
var_output : VAR_OUTPUT^ (var_def)+ END_VAR!;
var_def : ID^ COLON! data_type SEMICOLON! (range)? ;
// Fuzzify
fuzzify_block : FUZZIFY^ ID (linguistic_term)* END_FUZZIFY!;
linguistic_term: TERM^ ID ASSIGN_OPERATOR! membership_function SEMICOLON!;
membership_function : function | singleton | singletons | piece_wise_linear | gauss | gauss2 | trian | trape | sigm | gbell | cosine | dsigm ;
cosine: COSINE^ atom atom;
dsigm: DSIGM^ atom atom atom atom;
gauss: GAUSS^ atom atom;
gauss2: GAUSS2^ atom atom atom atom;
gbell: GBELL^ atom atom atom;
piece_wise_linear: (points)+;
sigm: SIGM^ atom atom;
singleton : atom;
singletons: SINGLETONS^ (points)+ ;
trape: TRAPE^ atom atom atom atom;
trian: TRIAN^ atom atom atom;
points : LEFT_PARENTHESIS x=atom COMMA y=atom RIGHT_PARENTHESIS -> ^(POINT $x $y);
atom : real | id;
id : x=ID -> ^(VALUE_ID $x);
real : x=REAL -> ^(VALUE_REAL $x);
// Functions (for singletons)
function: FUNCTION^ fun_pm;
fun_pm: fun_md ((PLUS^ | MINUS^ ) fun_md)*; // Function plus or minus
fun_md: fun_mp ((STAR^ | SLASH^) fun_mp)*; // Function multiply or divide
fun_mp : fun_atom ((HAT^ | PERCENT^) fun_atom)*; // Function modulus or power
fun_atom : atom | (EXP^|LN^|LOG^|SIN^|COS^|TAN^|ABS^)? LEFT_PARENTHESIS! fun_pm RIGHT_PARENTHESIS!; // Atom and parenthesis
// Defuzzify
defuzzify_block : DEFUZZIFY^ ID (defuzzify_item)* END_DEFUZZIFY!;
defuzzify_item : defuzzification_method | default_value | linguistic_term | range;
range : RANGE^ ASSIGN_OPERATOR! LEFT_PARENTHESIS! REAL DOTS! REAL RIGHT_PARENTHESIS! SEMICOLON!;
defuzzification_method : METHOD^ COLON! (COG|COGS|COGF|COA|LM|RM|MM) SEMICOLON!;
default_value : DEFAULT^ ASSIGN_OPERATOR! (REAL | NC) SEMICOLON!;
// Ruleblock
rule_block : RULEBLOCK^ ID (rule_item)* END_RULEBLOCK!;
rule_item : operator_definition | activation_method | accumulation_method | rule;
operator_definition : operator_definition_or | operator_definition_and;
operator_definition_or : OR^ COLON! (MAX|ASUM|BSUM|DMAX|NIPMAX|EINSTEIN) SEMICOLON!;
operator_definition_and : AND^ COLON! (MIN|PROD|BDIF|DMIN|NIPMIN|HAMACHER) SEMICOLON!;
activation_method : ACT^ COLON! (PROD|MIN) SEMICOLON!;
accumulation_method : ACCU^ COLON! (MAX|BSUM|NSUM|PROBOR|SUM) SEMICOLON!;
rule : RULE^ rule_name COLON! if_clause then_clause (with)? SEMICOLON! ;
rule_name : ID | REAL;
if_clause : IF^ condition;
then_clause : THEN^ conclusion;
condition : subcondition ((AND^|OR^) subcondition)*;
subcondition : (NOT^)? (subcondition_bare | subcondition_paren);
subcondition_bare : ID^ (IS! (NOT)? ID)? ;
subcondition_paren : LEFT_PARENTHESIS^ condition RIGHT_PARENTHESIS!;
conclusion : sub_conclusion (COMMA! sub_conclusion)*;
sub_conclusion : ID^ IS! ID;
with: WITH^ REAL;
// Data type
data_type : TYPE_REAL;