mirror of
https://github.com/marcin-szczepanski/jFuzzyLogic.git
synced 2024-12-18 16:35:27 +01:00
236 lines
9.0 KiB
Plaintext
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;
|
|
|