Создание грамматики языка программирования ST в нотации ANTLR4
Пытаюсь создать грамматику языка программирования ST для последующего анализа исходных кодов с помощью ANTLR. Проблема в том, что при использовании созданной грамматики при построении дерева путаются имена переменных и имена функций. Например, в программе
PROGRAM Program3
T := COS(28.4);
END_PROGRAM
COS воспринимается как имя переменной. Подскажите, пожалуйста, как изменить грамматику, чтобы это устранить. Грамматика лексера:
lexer grammar StLexer;
AND
: 'AND'
;
CASE
: 'CASE'
;
DIV
: 'DIV'
;
DO
: 'DO'
;
ELSE
: 'ELSE'
;
FOR
: 'FOR'
;
GOTO
: 'GOTO'
;
IF
: 'IF'
;
LABEL
: 'LABEL'
;
NOT
: 'NOT'
;
OF
: 'OF'
;
OR
: 'OR'
;
XOR
: 'XOR'
;
PROGRAM
: 'PROGRAM'
;
REPEAT
: 'REPEAT'
;
SET
: 'SET'
;
THEN
: 'THEN'
;
TO
: 'TO'
;
UNTIL
: 'UNTIL'
;
WHILE
: 'WHILE'
;
BY
:'BY'
;
PLUS
: '+'
;
MINUS
: '-'
;
STAR
: '*'
;
SLASH
: '/'
;
ASSIGN
: ':='
;
COMMA
: ','
;
SEMI
: ';'
;
COLON
: ':'
;
EQUAL
: '='
;
NOT_EQUAL
: '<>'
;
LT
: '<'
;
LE
: '<='
;
GE
: '>='
;
GT
: '>'
;
LPAREN
: '('
;
RPAREN
: ')'
;
LBRACK
: '['
;
RBRACK
: ']'
;
DOT
: '.'
;
TRUE
: 'TRUE'
;
FALSE
: 'FALSE'
;
ELSIF
:
'ELSIF'
;
ENDIF
: 'END_IF'
;
ENDCASE
: 'END_CASE'
;
ENDWHILE
: 'END_WHILE'
;
ENDREPEAT
: 'END_REPEAT'
;
ENDFOR
: 'END_FOR'
;
RETURN
: 'RETURN'
;
EXIT
: 'EXIT'
;
WS
: [ \t\r\n] -> skip
;
COMMENT_1
: '(*' .*? '*)' -> skip
;
PROGRAMNAME
:
('Program') ('0' .. '9' | '_')*
;
STRING_LITERAL
: '\'' ('\'\'' | ~ ('\''))* '\''
;
NUM_INT
: ('0' .. '9') +
;
NUM_REAL
: ('0' .. '9') + (('.' ('0' .. '9') + (EXPONENT)?)? | EXPONENT)
;
fragment EXPONENT
: ('E') ('+' | '-')? ('0' .. '9') +
;
ENDPROGRAM
:'END_PROGRAM'
;
IDENT
: ('A' .. 'Z' | )+('A' .. 'Z' | 'a' .. 'z' | '0' .. '9')*
;
STRUCTFIELD
:
(('A' .. 'Z')+ | '_')('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_')* '.'('X' | 'LastX' | 'Y' | 't' | 'cp' | 'c_p' | 'h' | 'Sm' | 'Sb' | 'CurNum' | 'Sost' | 'Time_oj' | 'NextNum' | 'q' | 'et' | 'tags' | 'locals_missing' | 'remotes_missing'
| 'resources_missing'
| 'type_mismatches'
| 'errors'
| 'timeouts'
| 'last_changes_sec'
| 'last_changes_nsec'
| 'last_idle_sec'
| 'last_idle_nsec'
| 'last_changes_str'
| 'last_idle_str'
| 'local_missing_def'
| 'remote_missing_def'
| 'resources_missing_def'
| 'type_mismatch_def'
| 'active_ip'
| 'ValueBOOL'
| 'ValueDINT'
| 'ValueREAL'
| 'Status'
| 'resource_missing'
| 'last_changes_ttime'
| 'last_idle_ttime' | 'last_changes'
| 'last_idle' | 'Value' | 'Valid' | 'Measurement' | 'DateTime' | 'Quality')
;
DEFAULTVAL
: '.'('A' .. 'Z')('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_')*
;
//Нетерминалы для стандартных функций ST
ANY_TO_BOOL
:'ANY_TO_BOOL'
;
ANY_TO_BYTE
:'ANY_TO_BYTE'
;
ANY_TO_DATE
:'ANY_TO_DATE'
;
ANY_TO_DINT
:'ANY_TO_DINT'
;
ANY_TO_DWORD
:'ANY_TO_DWORD'
;
ANY_TO_INT
:'ANY_TO_INT'
;
ANY_TO_LINT
:'ANY_TO_LINT'
;
ANY_TO_LREAL
:'ANY_TO_LREAL'
;
ANY_TO_REAL
:'ANY_TO_REAL'
;
ANY_TO_SINT
:'ANY_TO_SINT'
;
ANY_TO_STRING
:'ANY_TO_STRING'
;
ANY_TO_TIME
:'ANY_TO_TIME'
;
ANY_TO_ULINT
:'ANY_TO_ULINT'
;
ANY_TO_WORD
:'ANY_TO_WORD'
;
ABS//(float arg)
:'ABS'
;
ACOS//(float arg)
:'ACOS'
;
AND_MASK//(long In, long MSK)
:'AND_MASK'
;
ASCII//(std::string In, long Pos)
:'ASCII'
;
ASIN//(float In)
:'ASIN'
;
ATAN//(float In)
:'ATAN'
;
STCHAR//(long Code)
:'STCHAR'
;
COS//(float In)
:'COS'
;
//CURRENT_ISA_DATE
//:'CURRENT_ISA_DATE'
//;
DELETE//(long NbC, long Pos)
:'DELETE'
;
EXPT//(float In, long EXP)
:'EXPT'
;
FIND//(std::string In, std::string Pat)
:'FIND'
;
INSERT//(std::string In, std::string Str, long Pos)
:'INSERT'
;
LEFT//(std::string In, long NbC)
:'LEFT'
;
LIMIT//(long MIN, long In, long MAX)
:'LIMIT'
;
LOG//(float In)
:'LOG'
;
MAX//(long IN1, long IN2)
:'MAX'
;
MID//(std::string In, long NbC, long Pos)
:'MID'
;
MIN//(long IN1, long IN2)
:'MIN'
;
MLEN//(std::string In)
:'MLEN'
;
MOD//(long In, long Base)
:'MOD'
;
MUX4//(long SEL, long IN1, long IN2, long IN3, long IN4)
:'MUX4'
;
MUX8//(long SEL, long IN1, long IN2, long IN3, long IN4, long IN5, long IN6, long IN7, long IN8)
:'MUX8'
;
NOT_MASK//(long In)
:'NOT_MASK'
;
ODD
:'ODD'//(long In)
;
OR_MASK//(long In, long MSK)
:'OR_MASK'
;
POW//(float In, float EXP);
:'POW'
;
RAND//(long base)
:'RAND'
;
REPLACE//(std::string In, std::string Str, long NbC, long Pos)
:'REPLACE'
;
RIGHT//(std::string In, long NbC);
:'RIGHT'
;
ROL//(unsigned long In, unsigned long NbR)
:'ROL'
;
ROR//(unsigned long In, unsigned long NbR)
:'ROR'
;
SEL//bool SEL, long IN1, long IN2)
:'SEL'
;
SHL//(long In, long NbS)
:'SHL'
;
SHR//(long In, long NbS)
:'SHR'
;
SIN//(float In)
:'SIN'
;
SQRT//(float In)
:'SQRT'
;
TAN
:'TAN'//(float In)
;
TRUNC//(float In)
:'TRUNC'
;
XOR_MASK//(long In, long MSK)
:'XOR_MASK'
;
Грамматика парсера:
parser grammar StParser;
options
{
tokenVocab = StLexer;
}
program
: progHead = programHeading coddeBlock = statements progEnd = programEnd EOF
;
programEnd
:ENDPROGRAM
;
programHeading
: PROGRAM progName = programName
;
identifier
: IDENT
;
//Определние выражения (expression)
expression
: simpleExpression (relationaloperator expression)?
;
relationaloperator
: EQUAL
| NOT_EQUAL
| LT
| LE
| GE
| GT
;
simpleExpression
: term (additiveoperator simpleExpression)?
;
additiveoperator
: PLUS
| MINUS
| OR | XOR
;
term
: signedFactor (multiplicativeoperator term)?
;
multiplicativeoperator
: STAR
| SLASH
| DIV
| MOD
| AND
;
signedFactor
: (PLUS | MINUS)? factor
;
factor
: functionDesignator
| LPAREN expression RPAREN
| variable
| unsignedConstant
| NOT factor
| bool_
;
unsignedConstant
: unsignedNumber
| string
;
functionDesignator
: functionName LPAREN parameterList RPAREN
;
parameterList
: actualParameter (COMMA actualParameter)*
;
actualParameter
: expression | variable | STRUCTFIELD
;
//конец спичка всех составляющих выражения (expression)
functionName
:
ANY_TO_BOOL | ANY_TO_BYTE | ANY_TO_DATE | ANY_TO_DINT | ANY_TO_DWORD
| ANY_TO_INT | ANY_TO_LINT | ANY_TO_LREAL | ANY_TO_REAL | ANY_TO_SINT
| ANY_TO_STRING | ANY_TO_TIME | ANY_TO_ULINT | ANY_TO_WORD | ABS
| ACOS | AND_MASK | ASCII | ASIN | ATAN | STCHAR | COS | DELETE | EXPT
| FIND | INSERT | LEFT | LIMIT | LOG | MAX | MID | MIN | MLEN | MOD | MUX4
| MUX8 | NOT_MASK | ODD | OR_MASK | POW | RAND | REPLACE | RIGHT | ROL | ROR | SEL | SHL | SHR | SIN | SQRT
| TAN | TRUNC | XOR_MASK
;
programName
:
PROGRAMNAME
;
label
: unsignedInteger
;
constant
: unsignedNumber
| signedNumber
| identifier
| signedIdentirier
| string
;
signedNumber
: sign unsignedNumber
;
signedIdentirier
: sign identifier
;
unsignedNumber
: unsignedInteger
| unsignedReal
;
unsignedInteger
: NUM_INT
;
unsignedReal
: NUM_REAL
;
sign
: PLUS
| MINUS
;
bool_
: TRUE
| FALSE
;
string
: STRING_LITERAL
;
constList
: constant (COMMA constant)*
;
statement
:
(labeledStatement | unlabelledStatement) SEMI
;
labeledStatement
:
label COLON unlabelledStatement
;
unlabelledStatement
: assignmentStatement | procedureStatement | fbStatement
| ifStatement | caseStatement | whileStatement | repeatStatement | forStatement | returnStatement | exitStatement | gotoStatement
;
returnStatement
:RETURN
;
exitStatement
:EXIT
;
fbStatement
:
exemplarName = variable constructor = fbConstructor
;
fbConstructor
:
LPAREN fbParams = fbConstrVarList RPAREN
;
fbConstrVarList
:
fbConstrParametr(COMMA fbConstrParametr)*
;
fbConstrParametr
:
(variable | defaultValue)
;
defaultValue
: DEFAULTVAL
;
assignmentStatement
: (structField | variable) op = ASSIGN right = assignmentRigrtPart
;
assignmentRigrtPart
: procedureStatement | structField | variable |expression ;
variable
: identifier (massElement)?
;
massElement: LBRACK expression RBRACK;
structField: STRUCTFIELD;
//Вызов функции
procedureStatement
:
functionName LPAREN parameterList RPAREN
;
gotoStatement
: GOTO label
;
statements
: (statement)+
;
ifStatement
: IF expression THEN statements (ELSIF expression THEN statements)? ( ELSE statements)? ENDIF
;
caseStatement
: CASE expression OF caseListElement (caseListElement)* (ELSE statements)? ENDCASE
;
caseListElement
: constList COLON statement
;
whileStatement
: WHILE expression DO statements ENDWHILE
;
repeatStatement
: REPEAT statements UNTIL expression ENDREPEAT
;
forStatement
: FOR assignmentStatement forList (BY forStepValue)? DO statements ENDFOR
;
forList
: TO (finalValue | NUM_REAL | NUM_INT)
;
initialValue
: expression | NUM_INT | NUM_REAL
;
finalValue
: expression
;
forStepValue
:expression
;