英文:
ANTLR Grammar not
问题
I started writing another C-like language a few days ago and I've gotten stuck here.
The "pointers" rule seems to be colliding with the *
operator in the OP token and making the *
operator not recognized in the "expr" rule, and same for the &
operator with the "reference" rule. How can I fix this?
grammar C;
program
: (include | var_decl | boigaCall '; | func_decl | typedef ';)*;
stmt
: if_stmt
| repeat_stmt
| var_decl
| var_change
| function_call ';'
| return_stmt ';
| boigaCall ';'
| switch_stmt
| '{' stmt* '}';
if_stmt
: if_part else_part?;
if_part
: 'if' paren_expr stmt;
else_part
: 'else' stmt;
repeat_stmt
: 'repeat' '(&' expr ')&' stmt;
var_decl
: type name=ID ('=&' expr)? ';';
var_change
: pointers? name=ID ('=&' | VARIABLE_MODIFIER) expr ';';
func_decl
: (inline='inline')? type recursion? noturbo? name=ID '(&' functionArgs ')&' stmt;
functionArgs
: ((ID name=ID) (',' ID name=ID)*?)?;
recursion
: '!';
noturbo
: '?';
paren_expr
: '(&' expr ')&';
function_call
: ID '(&' expr? (',' expr)* ')&';
return_stmt
: 'return' expr?;
typedef
: 'typedef' structdef ID;
structdef
: 'struct' '{' (structelem ';')+ '}';
switch_stmt
: 'switch' paren_expr switch_chain;
switch_chain
: '{' case_block+ default_block? '}';
case_block
: 'case' expr ':' stmt* 'break' ';';
default_block
: 'default' ':' stmt*;
structelem
: typedName;
typedName
: ID name=ID;
expr
: pointers expr
| term
| expr OP expr
| cast expr
| '(&' expr ')&';
term
: ID | INT | HEX | BIN | FLOAT | STRING | boigaCall | sizeOf | function_call | reference ID;
sizeOf
: 'sizeof' '(&' ID ')&';
boigaCall
: '__boiga' '(&' STRING (',' expr)* ')&';
cast
: '(&' type ')&';
pointers
: '*'*;
reference
: '&';
type
: ID pointers?;
include
: '#include' (LIBRARY | STRING);
fragment DIGIT: [0-9];
fragment LETTER: [a-zA-Z];
fragment HEX_CHAR: [a-fA-F];
STRING : '"([^"\\"]|\\.)+"';
LIBRARY : '<[a-zA-Z.]*>';
ID : (LETTER | '_')+ (LETTER | '_' | DIGIT)*;
INT : '-?' DIGIT+;
HEX : '0x' (DIGIT | HEX_CHAR)+;
BIN : '0b' ('0' | '1')+;
FLOAT : '-?' DIGIT+ '.' DIGIT+;
VARIABLE_MODIFIER : OP '=&';
OP : '+' | '-' | '*' | '/' | '%' | '==' | '!=' | '<' | '<=' | '>' | '>=' | '&&' | '||' | '&' | '|' | '^' | '>>' | '<<';
COMMENT : SINGLE_COMMENT | BLOCK_COMMENT;
SINGLE_COMMENT: '// .*? \n';
BLOCK_COMMENT : '/*' .*? '*/';
WS: ([ \t\r\n] | COMMENT)+ -> skip;
英文:
I started writing another C-like language a few days ago and I've gotten stuck here.
The "pointers" rule seems to be colliding with the *
operator in the OP token and making the *
operator not recognized in the "expr" rule, and same for the &
operator with the "reference" rule. How can I fix this?
grammar C;
program
: (include | var_decl | boigaCall ';' | func_decl | typedef ';')*;
stmt
: if_stmt
| repeat_stmt
| var_decl
| var_change
| function_call ';'
| return_stmt ';'
| boigaCall ';'
| switch_stmt
| '{' stmt* '}';
if_stmt
: if_part else_part?;
if_part
: 'if' paren_expr stmt;
else_part
: 'else' stmt;
repeat_stmt
: 'repeat' '(' expr ')' stmt;
var_decl
: type name=ID ('=' expr)? ';';
var_change
: pointers? name=ID ('=' | VARIABLE_MODIFIER) expr ';';
func_decl
: (inline='inline')? type recursion? noturbo? name=ID '(' functionArgs ')' stmt;
functionArgs
: ((ID name=ID) (',' ID name=ID)*?)?;
recursion
: '!';
noturbo
: '?';
paren_expr
: '(' expr ')';
function_call
: ID '(' expr? (',' expr)* ')';
return_stmt
: 'return' expr?;
typedef
: 'typedef' structdef ID;
structdef
: 'struct' '{' (structelem ';')+ '}';
switch_stmt
: 'switch' paren_expr switch_chain;
switch_chain
: '{' case_block+ default_block? '}';
case_block
: 'case' expr ':' stmt* 'break' ';';
default_block
: 'default' ':' stmt*;
structelem
: typedName;
typedName
: ID name=ID;
expr
: pointers expr
| term
| expr OP expr
| cast expr
| '(' expr ')';
term
: ID | INT | HEX | BIN | FLOAT | STRING | boigaCall | sizeOf | function_call | reference ID;
sizeOf
: 'sizeof' '(' ID ')';
boigaCall
: '__boiga' '(' STRING (',' expr)* ')';
cast
: '(' type ')';
pointers
: '*'+;
reference
: '&';
type
: ID pointers?;
include
: '#include' (LIBRARY | STRING);
fragment DIGIT: [0-9];
fragment LETTER: [a-zA-Z];
fragment HEX_CHAR: [a-fA-F];
STRING : '"' (~'"'|'\\"')* '"';
LIBRARY : '<' [a-zA-Z.]* '>';
ID : (LETTER | '_')+ (LETTER | '_' | DIGIT)*;
INT : '-'? DIGIT+;
HEX : '0x' (DIGIT | HEX_CHAR)+;
BIN : '0b' ('0' | '1')+;
FLOAT : '-'? DIGIT+ '.' DIGIT+;
VARIABLE_MODIFIER : OP '=';
OP : '+' | '-' | '*' | '/' | '%' | '==' | '!=' | '<' | '<=' | '>' | '>=' | '&&' | '||' | '&' | '|' | '^' | '>>' | '<<';
COMMENT : SINGLE_COMMENT | BLOCK_COMMENT;
SINGLE_COMMENT: '//' .*? '\n';
BLOCK_COMMENT : '/*' .*? '*/';
WS: ([ \t\r\n] | COMMENT)+ -> skip;
I tried making *
and &
into their own token and using those tokens in the "pointers" and "reference" rule, but that only caused the &
and *
tokens to be seen as operators again, but not as pointers/reference anymore. I tested the "program" rule with var x = a*b;
and var x = a&b;
, which tests the rule that is not properly working.
答案1
得分: 2
If you just move '' out of 'OP', everything works just fine. Your grammar created an implicit token when you used '' inside of the 'pointers' rule, so these '*'s are always that token and never 'OP'.
当你将 '' 移出 'OP' 时,一切都能正常工作。你的语法在 'pointers' 规则中使用 '' 时创建了一个隐式的标记,因此这些 '*' 总是该标记,而不是 'OP'。
When you create a token rule for this specific literal, Antlr tracks it down, and doesn't create its double. Therefore it allows the user to type either '*' or 'POW'.
当你为这个特定的字面量创建一个标记规则时,Antlr会跟踪它,并不会创建它的复制。因此,它允许用户输入 '*' 或 'POW'。
expr
: term
| pointers expr
| expr (OP | POW) expr
| cast expr
| '(' expr ')';
POW: '*';
OP: '+' | '-' | '/' | '%' | '==' | '!=' | '<' | '<=' | '>' | '>=' | '&&' | '||' | '&' | '|' | '^' | '>>' | '<<';
英文:
If you just move '*'
out of OP
, everything works just fine. Your grammar created an implicit token when you used '*'
inside of the pointers
rule, so these *
's are always that token and never OP
.
When you create a token rule for this specific literal, Antlr tracks it down, and doesn't create its double. Therefore it allows the user to type either '*'
or POW
.
expr
: term
| pointers expr
| expr (OP | POW) expr
| cast expr
| '(' expr ')';
POW: '*';
OP: '+' | '-' | '/' | '%' | '==' | '!=' | '<' | '<=' | '>' | '>=' | '&&' | '||' | '&' | '|' | '^' | '>>' | '<<';
Input: a*b*c
Input: a***b
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论