📄 syntax.g
字号:
header{
#include "ANTLRExt.h"
#include "data_type.h"
#include "symbols.h"
#include <string>
using namespace std;
}
options{
language="Cpp";
}
class Datalexer extends Lexer;
options
{
charVocabulary = '\0'..'\377';
testLiterals=false;
defaultErrorHandler = false;
k=4;
}
APOSTROPHE :'\'';
SEMI :';';
COLON :':';
ASSIGN :'=';
protected DIGIT
: '0'..'9';
INT
options {
paraphrase = "an integer value";
}
: (DIGIT)+ // base-10
( '.' (DIGIT)* {$setType(DOUBLE);}
(('e' | 'E') ('+' | '-')? (DIGIT)+)?
| ('e' | 'E') ('+' | '-')? (DIGIT)+ {$setType(DOUBLE);}
)?
;
HEX
options {
paraphrase = "a hexadecimal integer value";
}
:'0' ('X'|'x')('a'..'f'|DIGIT|'A'..'F')+
;
DOUBLE
options {
paraphrase = "an floating point value";
}
: '.' (DIGIT)+ (('e' | 'E') ('+' | '-')? (DIGIT)+)?
;
WS : ( ' '
| '\t'
| '\f'
// handle newlines
| ( "\r\n" // Evil DOS
| '\r' // Macintosh
| '\n' // Unix (the right way)
)
{ newline(); }
)
{ _ttype = ANTLR_USE_NAMESPACE(antlr)Token::SKIP; }
;
IDENT
options {
testLiterals = true;
paraphrase = "an identifer";
}
: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
;
BIT: 'b' APOSTROPHE ('0'|'1');
BITS:'B' APOSTROPHE ('0'|'1')+;
SL_COMMENT :
"//"
(~'\n')* '\n'
{ _ttype = antlr::Token::SKIP; newline(); }
;
ML_COMMENT
: "/*"
( { LA(2)!='/' }? '*'
| '\n' { newline(); }
| ~('*'|'\n')
)*
"*/"
{ $setType(antlr::Token::SKIP); }
;
CHAR
options {
paraphrase = "a character literal";
}
:
'\''
( ESC | ~'\'' )
'\''
;
STRING
options {
paraphrase = "a string literal";
}
:
'"'
(ESC|~'"')*
'"'
;
protected
ESC : '\\'
( 'n'
| 'r'
| 't'
| 'b'
| 'f'
| '"'
| '\''
| '\\'
| '0'..'3'
(
options {
warnWhenFollowAmbig = false;
}
: DIGIT
(
options {
warnWhenFollowAmbig = false;
}
: DIGIT
)?
)?
| '4'..'7'
(
options {
warnWhenFollowAmbig = false;
}
: DIGIT
)?
)
;
//#############################################################################
//#############################################################################
class DataParser extends Parser;
options
{
genHashLines = true; // include line number information
buildAST = true; // uses CommonAST by default
defaultErrorHandler = false;
ASTLabelType = "RefASTNodeExt"; //uses user defination ASTNodeType
k=3;
}
tokens
{
BLOCK;
PROGRAM;
DEFASSIGN;
}
program
:(statement)*
{## =#([PROGRAM, "PROGRAM"], ##);}
;
definition
:var_def
;
var_def
:type_name COLON!
(
IDENT (ASSIGN! expression ) {## =#([DEFASSIGN, "DEFASSIGN"], ##);}
|IDENT (COMMA! IDENT)*
) SEMI!
;
const_value
:BIT
|BITS
|INT
|HEX
|DOUBLE
|CHAR
|STRING
|"true"
|"false"
;
type_name
:"bit"
|"bits"
|"uint8"
|"char"
|"string"
|"uint16"
|"int16"
|"int"
|"uint"
|"float"
|"double"
|"bool"
;
block
:LCURLY!
(statement)*
RCURLY!
{## = #([BLOCK, "BLOCK"], ##);}
;
statement
:definition
|assign_statement
|block
;
expression
:const_value
|IDENT;
assign_statement
:IDENT ASSIGN^ expression SEMI!
;
//#############################################################################
//#############################################################################
class DataASTParser extends TreeParser;
options {
defaultErrorHandler = false;
ASTLabelType = "RefASTNodeExt";
}
{
CSymTable symtable;
/* define error deal with manner----whrow data type:class CompilerException */
void ERROR_IF(bool cond, int line, string msg) {
if (cond) {
throw CompilerException(line, msg);
}
}
}
program
:#(PROGRAM (statement)*)
{
symtable.SaveData("test.data");
}
;
definition
:var_def
;
var_def
{
TypeAttr t1,t2;
}
:#(DEFASSIGN
t1=type_name
id:IDENT
t2=expression
{
if(t2.IsConvertable(t1))//t2 can convert to t1
{
if(symtable.GetSymb(id->getText())==NULL)
symtable.AddSymb(t1,id->getText(),t2.value);
else
ERROR_IF(true, id->getLine(), "Identifier redefined!");
}
else
ERROR_IF(true, id->getLine(), "Data assign type error!");
}
)
|(t1=type_name
(ids:IDENT
{
if(symtable.GetSymb(id->getText())!=NULL)
ERROR_IF(false, id->getLine(), "Identifier redefined!");
else
symtable.AddSymb(t1,ids->getText(),"");
}
)*)
;
const_value returns [TypeAttr t]
:b:BIT
{
t.SetType(BIT_T);
t.SetValue(b->getText());
t.BitToStr();//resolve bit to 0/1 string
}
|bs:BITS
{
t.SetType(BITS_T);
t.SetValue(bs->getText());
ERROR_IF(!t.BitsToStr(),bs->getLine(),"bits length>32!");
}
|i:INT
{
t.IsInt();
t.SetValue(i->getText());
t.CalcLen();
}
|h:HEX
{
t.IsInt();
t.SetValue(h->getText());
t.HexToStr();
}
|d:DOUBLE
{
t.IsDouble();
t.SetValue(d->getText());
t.CalcLen();
}
|c:CHAR
{
t.SetType(CHAR_T);
t.SetValue(c->getText());
t.CharToStr();
}
|s:STRING
{
t.SetType(STR_T);
t.SetValue(d->getText());
t.StrToStr();
}
|"true"
{
t.SetType(BOOL_T);
t.SetValue("0");
}
|"false"
{
t.SetType(BOOL_T);
t.SetValue("1");
}
;
type_name returns [TypeAttr t]
:"bit"
{
t.SetType(BIT_T);
}
|"bits"
{
t.SetType(BITS_T);
}
|"uint8"
{
t.SetType(UCHAR_T);
}
|"char"
{
t.SetType(CHAR_T);
}
|"string"
{
t.SetType(STR_T);
}
|"uint16"
{
t.SetType(UINT16_T);
}
|"int16"
{
t.SetType(INT16_T);
}
|"int"
{
t.SetType(INT_T);
}
|"uint"
{
t.SetType(UINT_T);
}
|"float"
{
t.SetType(FLOOT_T);
}
|"double"
{
t.SetType(DOUBLE_T);
}
|"bool"
{
t.SetType(BOOL_T);
}
;
block
:#(BLOCK (statement)*)
;
statement
:definition
|assign_statement
|block
;
expression returns [TypeAttr t]
{CSymbol* symb;}
:t=const_value
|id:IDENT
{
symb=symtable.GetSymb(id->getText());
bool temp=symb==NULL;
string errors="undefined identifier:"+id->getText();
ERROR_IF(temp,id->getLine(),errors);
t=symb->GetAttr();
};
assign_statement
{
CSymbol* symb;
TypeAttr t1,t2;
}
:#(ASSIGN id:IDENT t2=expression)
{
symb=symtable.GetSymb(id->getText());
if(symb==NULL)
ERROR_IF(true,id->getLine(),"undefined identifier!");
else
{
t1=symb->GetAttr();
if(t2.IsConvertable(t1))//t2 can convert to t1
{
symtable.SetSymValue(id->getText(),t2.value);
}
else
ERROR_IF(true, id->getLine(), "data type uncompatiable!");
}
} ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -