Initial check in lib

This commit is contained in:
2026-01-03 18:33:48 +01:00
parent b20cd8e688
commit 5666f85e99
89 changed files with 36370 additions and 1 deletions
+356
View File
@@ -0,0 +1,356 @@
unit dpglib.DpgLexer;
lexer TDpgLexer;
options
{
testLiterals = false;
k = 2;
}
tokens
{
"unit";
"uses";
"const";
"type";
"lexer";
"parser";
"treeparser";
"options";
"tokens";
"memberdecl";
"memberdef";
"private";
"protected";
"public";
"returns";
"local";
"except";
"finally";
SEMPRED;
USES;
OPTIONS;
TOKENS;
}
// ----------------------------------------------------------------------------
// Simple tokens
// ----------------------------------------------------------------------------
LPAREN: '(';
RPAREN: ')';
RCURLY: '}';
COLON: ':';
SEMI: ';';
COMMA: ',';
ASSIGN: '=';
IMPLIES: "=>";
QUEST: '?';
PLUS: '+';
STAR: '*';
AT: '@';
NOT: '~';
OR: '|';
BANG: '!';
WILDCARD: '.';
RANGE: "..";
OPEN: '<';
CLOSE: '>';
CARET: '^';
TREE_BEGIN: "#(";
// ----------------------------------------------------------------------------
// Character literal
// ----------------------------------------------------------------------------
CHARLIT
: '\''! (ESC | ~'\'') '\''! ;
// ----------------------------------------------------------------------------
// String literal
// ----------------------------------------------------------------------------
STRINGLIT
: '"' (ESC | ~'"')* '"' ;
// ----------------------------------------------------------------------------
// Integer
// ----------------------------------------------------------------------------
INTEGER
local
{
i: integer;
v: integer;
}
:
(
DNUMBER
{
v := 0;
for i:=1 to Length( TokenText) do
begin
v := v * 10 + ord( TokenText[i]) - ord('0');
end;
TokenText := IntToStr( v);
}
|
XNUMBER
{
v := 0;
for i:=1 to Length( TokenText) do
begin
case TokenText[i] of
'0'..'9': v := v * 16 + ord(TokenText[i]) - ord('0');
'a'..'z': v := v * 16 + ord(TokenText[i]) - ord('a');
'A'..'Z': v := v * 16 + ord(TokenText[i]) - ord('A');
end;
end;
TokenText := IntToStr( v);
}
)
;
// ----------------------------------------------------------------------------
// Argument action
// ----------------------------------------------------------------------------
ARGACTION
:
'['!
(
options
{
generateAmbigWarnings = false;
}
: '\r' '\n' { newLine; }
| '\r' { newLine; }
| '\n' { newLine; }
| ~']'
)*
']'!
;
// ----------------------------------------------------------------------------
// Action
// ----------------------------------------------------------------------------
ACTION
:
'{'
(
options
{
generateAmbigWarnings = false;
}
: '\r' '\n' { newLine; }
| '\r' { newLine; }
| '\n' { newLine; }
| ~'}'
)*
'}'
( '?'! { _ttype := TT_SEMPRED; } )?
;
// ----------------------------------------------------------------------------
// Token ref
// ----------------------------------------------------------------------------
TOKENREF
options
{
testLiterals = true;
}
: 'A'..'Z' ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')* ;
// ----------------------------------------------------------------------------
// Rule ref
// ----------------------------------------------------------------------------
RULEREF
local
{
t: integer;
}
:
t = INT_RULEREF { _ttype := t; }
(
{t = LT_uses}? WS_LOOP ('{' { _ttype := TT_USES; } )?
| {t = LT_options}? WS_LOOP ('{' { _ttype := TT_OPTIONS; } )?
| {t = LT_tokens}? WS_LOOP ('{' { _ttype := TT_TOKENS; } )?
)?
;
// ----------------------------------------------------------------------------
// Internal rule ref
// ----------------------------------------------------------------------------
protected
INT_RULEREF returns [integer]
{
_ttype := TT_RULEREF;
}
: 'a'..'z' ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*
{
result := TestLiteral( _ttype);
}
;
// ----------------------------------------------------------------------------
// COMMENT
// ----------------------------------------------------------------------------
COMMENT
: SLCOMMENT { _ttype := TT_SKIP; }
| MLCOMMENT1 { _ttype := TT_SKIP; }
| MLCOMMENT2 { _ttype := TT_SKIP; }
;
// ----------------------------------------------------------------------------
// SLCOMMENT
// ----------------------------------------------------------------------------
protected
SLCOMMENT
:
"//"
( ~( '\r' | '\n') )*
(
options
{
generateAmbigWarnings = false;
}
: '\r' '\n' { newLine; }
| '\r' { newLine; }
| '\n' { newLine; }
)
;
// ============================================================================
// Multi line comment version 1
// Nested comments aren't allowed!
// ============================================================================
protected
MLCOMMENT1
:
"(*"
(
options
{
greedy = false;
generateAmbigWarnings = false;
}
: '\r' '\n' { newLine; }
| '\r' { newLine; }
| '\n' { newLine; }
| .
)*
"*)"
;
// ============================================================================
// Multi line comment version 2
// Nested comments aren't allowed!
// ============================================================================
protected
MLCOMMENT2
:
"/*"
(
options
{
greedy = false;
generateAmbigWarnings = false;
}
: '\r' '\n' { newLine; }
| '\r' { newLine; }
| '\n' { newLine; }
| .
)*
"*/"
;
// ----------------------------------------------------------------------------
// Numbers
// ----------------------------------------------------------------------------
protected DNUMBER: '0'..'9' (DDIGIT)*;
protected XNUMBER: '$'! (XDIGIT)+;
// ----------------------------------------------------------------------------
// Digits
// ----------------------------------------------------------------------------
protected DDIGIT: '0'..'9';
protected XDIGIT: '0'..'9' | 'a'..'f' | 'A'..'F';
// ----------------------------------------------------------------------------
// WS
// ----------------------------------------------------------------------------
WS
:
(
options
{
generateAmbigWarnings = false;
}
: ' '
| '\t' { tab; }
| '\r' '\n' { newLine; }
| '\r' { newLine; }
| '\n' { newLine; }
)
{
_ttype := TT_SKIP;
}
;
// ----------------------------------------------------------------------------
// WS_LOOP
// ----------------------------------------------------------------------------
protected
WS_LOOP
:
(
options
{
greedy = true;
}
: WS
| COMMENT
)*
;
// ----------------------------------------------------------------------------
// Esc
// ----------------------------------------------------------------------------
protected
ESC
local
{
number: AnsiString;
}
:
'\\'!
(
'r' { TokenText[ Length( TokenText)] := AnsiChar(13); }
| 'n' { TokenText[ Length( TokenText)] := AnsiChar(10); }
| 't' { TokenText[ Length( TokenText)] := AnsiChar(9); }
| '\\'
| '\''
| '"'
| 'x' d1:XDIGIT! d2:XDIGIT!
{
number := '$' + d1.TokenText + d2.TokenText;
TokenText[ Length( TokenText)] := AnsiChar( StrToInt( number));
}
)
;
File diff suppressed because it is too large Load Diff
+77
View File
@@ -0,0 +1,77 @@
// ============================================================================
// This file is generated by the Delphi Parser Generator.
// ----------------------------------------------------------------------------
// DPG version: 2.1.0.0r
// Grammar: dpglib.dpgLexer.g
// ============================================================================
unit dpglib.DpgLexerTokens;
interface
const
TT_TREE_BEGIN = 46;
LT_finally = 21;
TT_QUEST = 34;
TT_INT_RULEREF = 54;
TT_IMPLIES = 33;
LT_returns = 18;
TT_WILDCARD = 41;
TT_OR = 39;
TT_CLOSE = 44;
TT_WS = 63;
LT_public = 17;
TT_RCURLY = 28;
TT_COMMA = 31;
LT_parser = 9;
LT_unit = 4;
TT_CHARLIT = 47;
LT_tokens = 12;
LT_uses = 5;
TT_SEMI = 30;
TT_ASSIGN = 32;
TT_OPEN = 43;
LT_treeparser = 10;
LT_memberdecl = 13;
TT_OPTIONS = 24;
TT_AT = 37;
LT_local = 19;
TT_SEMPRED = 22;
TT_CARET = 45;
TT_MLCOMMENT2 = 58;
TT_DDIGIT = 61;
LT_lexer = 8;
LT_memberdef = 14;
TT_RULEREF = 53;
LT_except = 20;
TT_COLON = 29;
TT_EOF = 1;
LT_protected = 16;
TT_INTEGER = 49;
TT_STAR = 36;
TT_ACTION = 51;
LT_type = 7;
LT_private = 15;
TT_LPAREN = 26;
TT_RPAREN = 27;
TT_BANG = 40;
TT_MLCOMMENT1 = 57;
TT_DNUMBER = 59;
TT_TOKENS = 25;
TT_ESC = 65;
TT_USES = 23;
TT_TOKENREF = 52;
TT_NOT = 38;
TT_SLCOMMENT = 56;
TT_STRINGLIT = 48;
TT_XDIGIT = 62;
TT_WS_LOOP = 64;
LT_options = 11;
LT_const = 6;
TT_ARGACTION = 50;
TT_RANGE = 42;
TT_PLUS = 35;
TT_XNUMBER = 60;
TT_COMMENT = 55;
implementation
end.
+65
View File
@@ -0,0 +1,65 @@
// $Delphi Parser Generator: dpglib.dpgLexer.g -> dpglib.dpgLexer.gTokens.txt$
TDpgLexer
TT_TREE_BEGIN=46
LT_finally="finally"=21
TT_QUEST=34
TT_INT_RULEREF=54
TT_IMPLIES=33
LT_returns="returns"=18
TT_WILDCARD=41
TT_OR=39
TT_CLOSE=44
TT_WS=63
LT_public="public"=17
TT_RCURLY=28
TT_COMMA=31
LT_parser="parser"=9
LT_unit="unit"=4
TT_CHARLIT=47
LT_tokens="tokens"=12
LT_uses="uses"=5
TT_SEMI=30
TT_ASSIGN=32
TT_OPEN=43
LT_treeparser="treeparser"=10
LT_memberdecl="memberdecl"=13
TT_OPTIONS=24
TT_AT=37
LT_local="local"=19
TT_SEMPRED=22
TT_CARET=45
TT_MLCOMMENT2=58
TT_DDIGIT=61
LT_lexer="lexer"=8
LT_memberdef="memberdef"=14
TT_RULEREF=53
LT_except="except"=20
TT_COLON=29
TT_EOF=1
LT_protected="protected"=16
TT_INTEGER=49
TT_STAR=36
TT_ACTION=51
LT_type="type"=7
LT_private="private"=15
TT_LPAREN=26
TT_RPAREN=27
TT_BANG=40
TT_MLCOMMENT1=57
TT_DNUMBER=59
TT_TOKENS=25
TT_ESC=65
TT_USES=23
TT_TOKENREF=52
TT_NOT=38
TT_SLCOMMENT=56
TT_STRINGLIT=48
TT_XDIGIT=62
TT_WS_LOOP=64
LT_options="options"=11
LT_const="const"=6
TT_ARGACTION=50
TT_RANGE=42
TT_PLUS=35
TT_XNUMBER=60
TT_COMMENT=55
+889
View File
@@ -0,0 +1,889 @@
unit dpglib.DpgParser;
uses
{
dpglib.types;
}
parser TDpgParser;
options
{
defaultErrorHandler = false;
importVocab = dpglib.DpgLexer;
exportVocab = dpglib.DpgParser;
k = 2;
}
memberdecl
{
protected
fGrammarMaker : IGrammarBehavior;
fTool : ITool;
fNesting : integer;
fExchangeDir : AnsiString;
fGrammarFile : AnsiString;
fGrammarUnit : AnsiString;
private
function lastInRule : boolean;
procedure checkEndRule( pToken: IToken);
public
constructor Create( pParserState : IParserState;
pGrammarMaker : IGrammarBehavior;
pTool : ITool;
pExchangeDir : AnsiString); overload;
constructor Create( pTokenBuffer : ITokenBuffer;
pGrammarMaker : IGrammarBehavior;
pTool : ITool;
pExchangeDir : AnsiString); overload;
constructor Create( pTokenStream : ITokenStream;
pGrammarMaker : IGrammarBehavior;
pTool : ITool;
pExchangeDir : AnsiString); overload;
destructor Destroy; override;
}
// ----------------------------------------------------------------------------
// grammar
// ----------------------------------------------------------------------------
grammar
local
{
unitName: IToken;
}
:
"unit" unitName=qualifiedId {fGrammarUnit := unitName.TokenText;} SEMI
(usesDecl)?
(constDecl)?
(typeDecl)?
classDecl
{fGrammarMaker.endGrammar;}
;
// ----------------------------------------------------------------------------
// usesDecl
// ----------------------------------------------------------------------------
usesDecl
:
USES
(
// tr:TOKENREF SEMI {fGrammarMaker.defineUses( tr);}
// | rr:RULEREF SEMI {fGrammarMaker.defineUses( rr);}
qualifiedUsesName SEMI
)*
RCURLY
;
qualifiedUsesName
local
{
id: AnsiString;
}
: ( r:TOKENREF | r:RULEREF ) { id := r.TokenText; }
( WILDCARD
( r:TOKENREF | r:RULEREF) { id := id +'.'+ r.TokenText; }
)*
{
fGrammarMaker.defineUses(id);
}
;
// ----------------------------------------------------------------------------
// constDecl
// ----------------------------------------------------------------------------
constDecl
:
"const"
a:ACTION {fGrammarMaker.RefConstAction( a);}
;
// ----------------------------------------------------------------------------
// typeDecl
// ----------------------------------------------------------------------------
typeDecl
:
"type"
a:ACTION {fGrammarMaker.RefTypeAction( a);}
;
// ----------------------------------------------------------------------------
// classDecl
// ----------------------------------------------------------------------------
classDecl
local
{
grType : integer;
grObject : IToken;
grSuper : IToken;
}
{
grObject := nil;
grSuper := nil;
}
:
// ------------------------------------------------------------
// Determine parser type
// ------------------------------------------------------------
( "lexer" { grType := 0; }
| "parser" { grType := 1; }
| "treeparser" { grType := 2; }
)
// ------------------------------------------------------------
// get class name
// ------------------------------------------------------------
grObject = id
// ------------------------------------------------------------
// get superclass name
// ------------------------------------------------------------
// (
// LPAREN
// grSuper=id
// RPAREN
// )?
SEMI
// ------------------------------------------------------------
// Start the grammar
// ------------------------------------------------------------
{
// ---------------------------------------------------------
// Now we have enough information to start the grammar.
// ---------------------------------------------------------
case grType of
0: fGrammarMaker.StartLexer( InputState.FileName,
grObject,
grSuper);
1: fGrammarMaker.StartParser( InputState.FileName,
grObject,
grSuper);
2: fGrammarMaker.StartTreeWalker( InputState.FileName,
grObject,
grSuper);
end;
fGrammarMaker.defineGrammarUnit( fGrammarUnit);
}
// ------------------------------------------------------------
// Process optional class "options {...}" clause
// ------------------------------------------------------------
(classOptions)?
// ------------------------------------------------------------
// Process optional class "tokens {...}" clause
// But only for lexers.
// ------------------------------------------------------------
( {grType=0}? classTokens)?
// ------------------------------------------------------------
// Process optional class "memberDecl {...}" clause
// ------------------------------------------------------------
(classMemberDecl)?
// ------------------------------------------------------------
// Well, the rules
// ------------------------------------------------------------
rules
// ------------------------------------------------------------
// Process optional class "memberDecl {...}" clause
// ------------------------------------------------------------
(classMemberDef)?
;
// ----------------------------------------------------------------------------
// classOptions
// ----------------------------------------------------------------------------
classOptions
local
{
optName : IToken;
optValue : IToken;
}
:
OPTIONS
(
optName = id
ASSIGN
optValue = optionValue
SEMI
{fGrammarMaker.setGrammarOption( optName, optValue);}
)*
RCURLY
;
// ----------------------------------------------------------------------------
// classTokens
// ----------------------------------------------------------------------------
classTokens
:
TOKENS
(
{
tokenName := nil;
tokenString := nil;
}
(
tokenName:TOKENREF (ASSIGN tokenString:STRINGLIT)?
{
fGrammarMaker.defineToken( tokenName, tokenString);
}
(tokenSpecOptions[tokenName])?
| tokenString:STRINGLIT
{
fGrammarMaker.defineToken( tokenName, tokenString);
}
(tokenSpecOptions[tokenString])?
)
SEMI
)*
RCURLY
;
// ----------------------------------------------------------------------------
// tokenSpecOptions
// ----------------------------------------------------------------------------
tokenSpecOptions[ t: IToken]
local
{
name : IToken;
value : IToken;
}
{
name := nil;
value := nil;
}
: OPEN
name=id ASSIGN value=optionValue
{
fGrammarMaker.refTokenSpecElemOption( t, name, value);
}
(
name=id ASSIGN value=optionValue
{
fGrammarMaker.refTokenSpecElemOption( t, name, value);
}
)*
CLOSE
;
// ----------------------------------------------------------------------------
// classMemberDecl
// ----------------------------------------------------------------------------
classMemberDecl
:
"memberDecl"
memberDecl:ACTION
{fGrammarMaker.refMemberDecl(memberDecl);}
;
// ----------------------------------------------------------------------------
// classMemberDef
// ----------------------------------------------------------------------------
classMemberDef
:
"memberDef"
memberDef:ACTION
{fGrammarMaker.refMemberDef(memberDef);}
;
// ----------------------------------------------------------------------------
// rules
// ----------------------------------------------------------------------------
rules
:
(rule)*
;
// ----------------------------------------------------------------------------
// ruleExceptionBlock
// ----------------------------------------------------------------------------
ruleExceptionBlock
:
t:"except" a:ACTION { fGrammarMaker.RefRuleExHandler( t, a); }
| t:"finally" a:ACTION { fGrammarMaker.RefRuleExHandler( t, a); }
;
// ----------------------------------------------------------------------------
// ruleExceptionBlock
// ----------------------------------------------------------------------------
altExceptionBlock
:
t:"except" a:ACTION { fGrammarMaker.RefAltExHandler( t, a); }
| t:"finally" a:ACTION { fGrammarMaker.RefAltExHandler( t, a); }
;
// ----------------------------------------------------------------------------
// rule
// ----------------------------------------------------------------------------
rule
local
{
access : AnsiString;
ag : integer;
returns : IToken;
name : IToken;
}
{
access := 'public';
args := nil;
name := nil;
ag := AUTOGEN_NONE;
}
:
// ------------------------------------------------------------
// Parse rule scope
// ------------------------------------------------------------
( "public" { access := 'public'; }
| "protected" { access := 'protected'; }
| "private" { access := 'private'; }
)?
// ------------------------------------------------------------
// Parse rule name
// ------------------------------------------------------------
name=id
// ------------------------------------------------------------
// Parse optional BANG operator
// ------------------------------------------------------------
// ( BANG { ag := AUTOGEN_BANG;} )?
// ------------------------------------------------------------
// Optional arguments
// ------------------------------------------------------------
( args:ARGACTION)?
// ------------------------------------------------------------
// Optional return type
// ------------------------------------------------------------
( "returns" ret:ARGACTION)?
// ------------------------------------------------------------
// Now start the rule definition
// ------------------------------------------------------------
{
fGrammarMaker.defineRuleName( name, access, true, '');
if args <> nil then
fGrammarMaker.refArgAction( args);
if ret <> nil then
fGrammarMaker.refReturnAction( ret);
}
// ------------------------------------------------------------
// Optional rule options
// ------------------------------------------------------------
(ruleOptions)?
// ------------------------------------------------------------
// Optional rule local variable declarations
// ------------------------------------------------------------
(
"local"
locals:ACTION
{fGrammarMaker.refRuleLocals( locals);}
)?
// ------------------------------------------------------------
// Optional rule init action
// ------------------------------------------------------------
(
initAction:ACTION
{fGrammarMaker.refInitAction( initAction);}
)?
// ------------------------------------------------------------
// Rule block
// ------------------------------------------------------------
COLON
block
SEMI
// ------------------------------------------------------------
// Optional exception handler
// ------------------------------------------------------------
( ruleExceptionBlock)?
// ------------------------------------------------------------
// Finish the rule
// ------------------------------------------------------------
{ fGrammarMaker.endRule('');}
;
// ----------------------------------------------------------------------------
// block
// ----------------------------------------------------------------------------
block
{
INC( fNesting);
}
: alternative (OR alternative)* {DEC(fNesting);}
;
// ----------------------------------------------------------------------------
// alternative
// ----------------------------------------------------------------------------
alternative
local
{
autoGen : boolean;
}
{
autoGen := true;
}
:
// (BANG {autoGen := false;})?
{fGrammarMaker.beginAlt( autoGen);}
(elem)*
(altExceptionBlock)?
{fGrammarMaker.endAlt;}
;
// ----------------------------------------------------------------------------
// elem
// ----------------------------------------------------------------------------
elem
: element (elementOptions)?
;
// ----------------------------------------------------------------------------
// element options
// ----------------------------------------------------------------------------
elementOptions
local
{
name : IToken;
value : IToken;
}
: OPEN
name=id ASSIGN value=optionValue
{
fGrammarMaker.refElemOption(name,value);
}
(
name=id ASSIGN value=optionValue
{
fGrammarMaker.refElemOption(name,value);
}
)*
CLOSE
;
// ----------------------------------------------------------------------------
// element
// ----------------------------------------------------------------------------
element
local
{
assignId : IToken;
assignLabel : IToken;
autoGen : integer;
}
{
assignId := nil;
assignLabel := nil;
autoGen := AUTOGEN_NONE;
}
:
(
assignId=id ASSIGN
(assignLabel=id COLON {checkEndRule(assignLabel);})?
(
ruleRef:RULEREF (args:ARGACTION)? (ag:BANG {autoGen := AUTOGEN_BANG;})?
{fGrammarMaker.refRule( assignId, ruleRef, assignLabel, args, autoGen);}
|
tokenRef:TOKENREF (args:ARGACTION)?
{fGrammarMaker.refToken( assignId, tokenRef, assignLabel, args, false, autoGen, lastInRule);}
)
)
|
(assignLabel=id COLON {checkEndRule(assignLabel);})?
(
ruleRef:RULEREF (args:ARGACTION)? (ag:BANG {autoGen := AUTOGEN_BANG;})?
{fGrammarMaker.refRule( assignId, ruleRef, assignLabel, args, autoGen);}
| range[assignLabel]
| terminal[assignLabel]
| NOT (notTerminal[assignLabel] | ebnf[ assignLabel, true])
| ebnf[ assignLabel, false]
)
|
action:ACTION
{fGrammarMaker.refAction( action);}
|
semPred:SEMPRED
{fGrammarMaker.refSemPred( semPred);}
|
tree
;
// ----------------------------------------------------------------------------
// tree
// ----------------------------------------------------------------------------
tree
: lp:TREE_BEGIN { fGrammarMaker.BeginTree(lp); }
rootNode { fGrammarMaker.BeginChildList; }
(element)+ { fGrammarMaker.EndChildList; }
RPAREN { fGrammarMaker.EndTree; }
;
// ----------------------------------------------------------------------------
// rootNode
// ----------------------------------------------------------------------------
rootNode
local
{
l : IToken;
}
: (
l=id COLON
{
CheckEndRule(l);
}
)?
terminal[l]
;
// ----------------------------------------------------------------------------
// range
// ----------------------------------------------------------------------------
range [pTokenLabel: IToken]
local
{
autoGen: integer;
}
{
autoGen := AUTOGEN_NONE;
}
:
crLeft:CHARLIT
RANGE
crRight:CHARLIT
(BANG {autoGen := AUTOGEN_BANG;} )?
{fGrammarMaker.refCharRange( crLeft, crRight, pTokenLabel, autoGen, lastInRule);}
|
(trLeft:TOKENREF | trLeft:STRINGLIT)
RANGE
(trRight:TOKENREF | trRight:STRINGLIT)
autoGen=astTypeSpec
{fGrammarMaker.refTokenRange( trLeft, trRight, pTokenLabel, autoGen, lastInRule);}
;
// ----------------------------------------------------------------------------
// terminal
// ----------------------------------------------------------------------------
terminal [pTokenLabel: IToken]
local
{
autoGen : integer;
}
{
autoGen := AUTOGEN_NONE;
aa := nil;
}
:
cl:CHARLIT
(BANG {autoGen := AUTOGEN_BANG;} )?
{fGrammarMaker.refCharLiteral( cl, pTokenLabel, false, autoGen, lastInRule);}
|
tr:TOKENREF
autoGen=astTypeSpec
(aa:ARGACTION)?
{fGrammarMaker.refToken( nil, tr, pTokenLabel, aa, false, autoGen, lastInRule);}
|
sl:STRINGLIT
autoGen=astTypeSpec
{fGrammarMaker.refStringLiteral( sl, pTokenLabel, autoGen, lastInRule);}
|
wc:WILDCARD
autogen=astTypeSpec
{fGrammarMaker.refWildCard( wc, pTokenLabel, autoGen);}
;
// ----------------------------------------------------------------------------
// notTerminal
// ----------------------------------------------------------------------------
notTerminal [pTokenLabel: IToken]
local
{
autoGen : integer;
}
{
autoGen := AUTOGEN_NONE;
}
:
cl:CHARLIT
(BANG {autoGen := AUTOGEN_BANG;} )?
{fGrammarMaker.refCharLiteral( cl, pTokenLabel, true, autoGen, lastInRule);}
|
tr:TOKENREF
autoGen=astTypeSpec
{fGrammarMaker.refToken( nil, tr, pTokenLabel, nil, true, autoGen, lastInRule);}
;
// ----------------------------------------------------------------------------
// ebnf
// ----------------------------------------------------------------------------
ebnf [pTokenLabel: IToken; pTokenNot: boolean]
:
lp:LPAREN
{fGrammarMaker.beginSubrule( pTokenLabel, lp, pTokenNot);}
(
// ---------------------------------------------------------
// 2nd alt and optional branch ambig due to linear approx
// LL(2) issue. COLON ACTION matched correctly in 2nd alt.
// ---------------------------------------------------------
options
{
warnWhenFollowAmbig = false;
}
:
subRuleOptions
(aa:ACTION {fGrammarMaker.refInitAction(aa);} )?
COLON
|
aa:ACTION {fGrammarMaker.refInitAction(aa);}
COLON
)?
block
RPAREN
(
( QUEST { fGrammarMaker.optionalSubrule; }
| STAR { fGrammarMaker.zeroOrMoreSubrule; }
| PLUS { fGrammarMaker.oneOrMoreSubrule; }
| AT { fGrammarMaker.nmSubrule; }
LPAREN
(
m:INTEGER { fGrammarMaker.refRangeLow( StrToInt(m.TokenText)); }
(
COMMA { fGrammarMaker.refRangeHigh( maxint); }
(
n:INTEGER { fGrammarMaker.refRangeHigh(StrToInt(n.TokenText)); }
)?
)?
|
COMMA
n:INTEGER { fGrammarMaker.refRangeHigh(StrToInt(n.TokenText)); }
)
RPAREN
| IMPLIES {fGrammarMaker.synPred; }
)?
// ( BANG {fGrammarMaker.noASTSubrule;} )?
)
{fGrammarMaker.endSubRule;}
;
// ----------------------------------------------------------------------------
// optionValue
// ----------------------------------------------------------------------------
optionValue returns [IToken]
:
result=qualifiedId
| result:STRINGLIT
| result:CHARLIT
| result:INTEGER
;
// ----------------------------------------------------------------------------
// subruleOptions
// ----------------------------------------------------------------------------
subruleOptions
local
{
optName : IToken;
optValue : IToken;
}
:
OPTIONS
(
optName = id
ASSIGN
optValue = optionValue
SEMI
{fGrammarMaker.setSubruleOption( optName, optValue);}
)*
RCURLY
;
// ----------------------------------------------------------------------------
// ruleOptions
// ----------------------------------------------------------------------------
ruleOptions
local
{
optName : IToken;
optValue : IToken;
}
:
OPTIONS
(
optName = id
ASSIGN
optValue = optionValue
SEMI
{fGrammarMaker.setRuleOption( optName, optValue);}
)*
RCURLY
;
// ----------------------------------------------------------------------------
// astTypeSpec
// ----------------------------------------------------------------------------
astTypeSpec returns [integer]
{
result := AUTOGEN_NONE;
}
:
( CARET { result := AUTOGEN_CARET; }
| BANG { result := AUTOGEN_BANG; }
)?
;
// ----------------------------------------------------------------------------
// qualifiedId
// ----------------------------------------------------------------------------
qualifiedId returns [IToken]
local
{
buf : AnsiString;
a : IToken;
}
:
a=id { buf := a.TokenText; }
(
WILDCARD a=id { buf := buf + '.' + a.TokenText; }
)*
{
// -----------------------------------------------------------
// Can either TOKENREF or RULEREF. Should really create QID or
// something else instead.
// -----------------------------------------------------------
result := TToken.Create( TT_TOKENREF, buf);
result.TokenLine := a.TokenLine;
result.TokenColumn := a.TokenColumn;
}
;
// ----------------------------------------------------------------------------
// id
// ----------------------------------------------------------------------------
id returns [IToken]
:
result:TOKENREF
| result:RULEREF
;
memberdef
{
// ============================================================================
// Constructor
// ============================================================================
constructor TDpgParser.Create( pParserState : IParserState;
pGrammarMaker : IGrammarBehavior;
pTool : ITool;
pExchangeDir : AnsiString);
begin
inherited Create( pParserState, 2);
fGrammarMaker := pGrammarMaker;
fExchangeDir := pExchangeDir;
fTool := pTool;
fNesting := 0;
end;
// ============================================================================
// Constructor
// ============================================================================
constructor TDpgParser.Create( pTokenBuffer : ITokenBuffer;
pGrammarMaker : IGrammarBehavior;
pTool : ITool;
pExchangeDir : AnsiString);
begin
inherited Create( pTokenBuffer, 2);
fGrammarMaker := pGrammarMaker;
fExchangeDir := pExchangeDir;
fTool := pTool;
fNesting := 0;
end;
// ============================================================================
// Constructor
// ============================================================================
constructor TDpgParser.Create( pTokenStream : ITokenStream;
pGrammarMaker : IGrammarBehavior;
pTool : ITool;
pExchangeDir : AnsiString);
begin
inherited Create( pTokenStream, 2);
fGrammarMaker := pGrammarMaker;
fExchangeDir := pExchangeDir;
fTool := pTool;
fNesting := 0;
end;
// ============================================================================
// Destructor
// ============================================================================
destructor TDpgParser.Destroy;
begin
fGrammarMaker := nil;
fTool := nil;
inherited;
end;
// ============================================================================
// lastInRule
// ============================================================================
function TDpgParser.lastInRule: boolean;
begin
if (fNesting = 0) and (LA(1) in [TT_SEMI, TT_OR])
then result := true
else result := false;
end;
// ============================================================================
// checkEndRule
// ============================================================================
procedure TDpgParser.checkEndRule( pToken: IToken);
begin
if pToken <> nil then
if pToken.TokenColumn = 1 then
fTool.Warning('Did you forget to close the previous rule?',
InputState.FileName,
pToken.TokenLine,
pToken.TokenColumn);
end;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,77 @@
// ============================================================================
// This file is generated by the Delphi Parser Generator.
// ----------------------------------------------------------------------------
// DPG version: 2.1.0.0r
// Grammar: dpglib.dpgParser.g
// ============================================================================
unit dpglib.DpgParserTokens;
interface
const
TT_TREE_BEGIN = 46;
LT_finally = 21;
TT_QUEST = 34;
TT_INT_RULEREF = 54;
TT_IMPLIES = 33;
LT_returns = 18;
TT_WILDCARD = 41;
TT_OR = 39;
TT_CLOSE = 44;
TT_WS = 63;
LT_public = 17;
TT_RCURLY = 28;
TT_COMMA = 31;
LT_parser = 9;
TT_CHARLIT = 47;
LT_unit = 4;
LT_tokens = 12;
LT_uses = 5;
TT_SEMI = 30;
TT_ASSIGN = 32;
TT_OPEN = 43;
LT_treeparser = 10;
LT_memberdecl = 13;
TT_OPTIONS = 24;
TT_AT = 37;
LT_local = 19;
TT_SEMPRED = 22;
TT_CARET = 45;
TT_MLCOMMENT2 = 58;
TT_DDIGIT = 61;
LT_lexer = 8;
LT_memberdef = 14;
TT_RULEREF = 53;
LT_except = 20;
TT_COLON = 29;
TT_EOF = 1;
LT_protected = 16;
TT_INTEGER = 49;
TT_STAR = 36;
TT_ACTION = 51;
LT_type = 7;
LT_private = 15;
TT_LPAREN = 26;
TT_RPAREN = 27;
TT_BANG = 40;
TT_MLCOMMENT1 = 57;
TT_DNUMBER = 59;
TT_TOKENS = 25;
TT_ESC = 65;
TT_USES = 23;
TT_TOKENREF = 52;
TT_NOT = 38;
TT_SLCOMMENT = 56;
TT_STRINGLIT = 48;
TT_XDIGIT = 62;
TT_WS_LOOP = 64;
LT_options = 11;
LT_const = 6;
TT_ARGACTION = 50;
TT_RANGE = 42;
TT_PLUS = 35;
TT_XNUMBER = 60;
TT_COMMENT = 55;
implementation
end.
@@ -0,0 +1,65 @@
// $Delphi Parser Generator: dpglib.dpgParser.g -> dpglib.dpgParser.gTokens.txt$
TDpgParser
TT_TREE_BEGIN=46
LT_finally="finally"=21
TT_QUEST=34
TT_INT_RULEREF=54
TT_IMPLIES=33
LT_returns="returns"=18
TT_WILDCARD=41
TT_OR=39
TT_CLOSE=44
TT_WS=63
LT_public="public"=17
TT_RCURLY=28
TT_COMMA=31
LT_parser="parser"=9
TT_CHARLIT=47
LT_unit="unit"=4
LT_tokens="tokens"=12
LT_uses="uses"=5
TT_SEMI=30
TT_ASSIGN=32
TT_OPEN=43
LT_treeparser="treeparser"=10
LT_memberdecl="memberdecl"=13
TT_OPTIONS=24
TT_AT=37
LT_local="local"=19
TT_SEMPRED=22
TT_CARET=45
TT_MLCOMMENT2=58
TT_DDIGIT=61
LT_lexer="lexer"=8
LT_memberdef="memberdef"=14
TT_RULEREF=53
LT_except="except"=20
TT_COLON=29
TT_EOF=1
LT_protected="protected"=16
TT_INTEGER=49
TT_STAR=36
TT_ACTION=51
LT_type="type"=7
LT_private="private"=15
TT_LPAREN=26
TT_RPAREN=27
TT_BANG=40
TT_MLCOMMENT1=57
TT_DNUMBER=59
TT_TOKENS=25
TT_ESC=65
TT_USES=23
TT_TOKENREF=52
TT_NOT=38
TT_SLCOMMENT=56
TT_STRINGLIT=48
TT_XDIGIT=62
TT_WS_LOOP=64
LT_options="options"=11
LT_const="const"=6
TT_ARGACTION=50
TT_RANGE=42
TT_PLUS=35
TT_XNUMBER=60
TT_COMMENT=55
+110
View File
@@ -0,0 +1,110 @@
unit dpglib.TokenLexer;
lexer TTokenLexer;
options
{
k = 2;
testLiterals = false;
}
// ----------------------------------------------------------------------------
// Simple tokens
// ----------------------------------------------------------------------------
LPAREN : '(';
RPAREN : ')';
ASSIGN : '=';
STRING : '"' (~'"')* '"';
// ----------------------------------------------------------------------------
// DIGIT
// ----------------------------------------------------------------------------
protected
DIGIT
: '0'..'9'
;
// ----------------------------------------------------------------------------
// XDIGIT
// ----------------------------------------------------------------------------
protected
XDIGIT
: '0'..'9'
| 'a'..'f'
| 'A'..'F'
;
// ----------------------------------------------------------------------------
// ID
// ----------------------------------------------------------------------------
ID
: ('a'..'z' | 'A'..'Z')
('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*
;
// ----------------------------------------------------------------------------
// INT
// ----------------------------------------------------------------------------
INT
: (DIGIT)+
;
// ----------------------------------------------------------------------------
// WS
// ----------------------------------------------------------------------------
WS
:
(
' '
| '\t'
| '\r' '\n' { newLine; }
| '\r' { newLine; }
| '\n' { newLine; }
)
{
_ttype := TT_SKIP;
}
;
// ----------------------------------------------------------------------------
// SLCOMMENT
// ----------------------------------------------------------------------------
SLCOMMENT
: "//"
( ~( '\r' | '\n'))*
(
options
{
generateAmbigWarnings = false;
}
: '\r' '\n' { newLine; }
| '\r' { newLine; }
| '\n' { newLine; }
)
{
_ttype := TT_SKIP;
}
;
// ----------------------------------------------------------------------------
// MLCOMMENT
// ----------------------------------------------------------------------------
MLCOMMENT
: "(*"
(
options
{
greedy = false;
generateAmbigWarnings= false;
}
: '\r' '\n' { newLine; }
| '\r' { newLine; }
| '\n' { newLine; }
| ~('\r' | '\n')
)*
"*)"
{
_ttype := TT_SKIP;
}
;
+622
View File
@@ -0,0 +1,622 @@
// ============================================================================
// This file is generated by the Delphi Parser Generator.
// ----------------------------------------------------------------------------
// DPG version: 2.1.0.0r
// Grammar: dpglib.tokenLexer.g
// ============================================================================
unit dpglib.TokenLexer;
interface
uses
System.Classes,
dpglib.TokenLexerTokens,
dpgrtl.lexer,
dpgrtl.types,
System.SysUtils;
type
// =========================================================================
// Class TTokenLexer declaration
// =========================================================================
TTokenLexer = class( TLexer)
public // Protected grammar rules
// Must callable from parser too
procedure mDIGIT ( pCreate: boolean);
procedure mXDIGIT ( pCreate: boolean);
public // Public grammar rules
procedure mLPAREN ( pCreate: boolean);
procedure mRPAREN ( pCreate: boolean);
procedure mASSIGN ( pCreate: boolean);
procedure mSTRING ( pCreate: boolean);
procedure mID ( pCreate: boolean);
procedure mINT ( pCreate: boolean);
procedure mWS ( pCreate: boolean);
procedure mSLCOMMENT ( pCreate: boolean);
procedure mMLCOMMENT ( pCreate: boolean);
public
function NextToken: IToken; override;
end;
implementation
uses
dpgrtl.exception,
dpgrtl.token;
// ============================================================================
// mLPAREN
// ============================================================================
procedure TTokenLexer.mLPAREN( pCreate: boolean);
var
_begin: integer;
_save: integer;
_token: IToken;
_ttype: integer;
begin
_begin := Length( TokenText) +1;
_token := nil;
_ttype := TT_LPAREN;
match('(');
if (_ttype <> TT_SKIP) and (pCreate = true) then
begin
_token := makeToken( _ttype);
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
end;
ReturnToken := _token;
end;
// ============================================================================
// mRPAREN
// ============================================================================
procedure TTokenLexer.mRPAREN( pCreate: boolean);
var
_begin: integer;
_save: integer;
_token: IToken;
_ttype: integer;
begin
_begin := Length( TokenText) +1;
_token := nil;
_ttype := TT_RPAREN;
match(')');
if (_ttype <> TT_SKIP) and (pCreate = true) then
begin
_token := makeToken( _ttype);
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
end;
ReturnToken := _token;
end;
// ============================================================================
// mASSIGN
// ============================================================================
procedure TTokenLexer.mASSIGN( pCreate: boolean);
var
_begin: integer;
_save: integer;
_token: IToken;
_ttype: integer;
begin
_begin := Length( TokenText) +1;
_token := nil;
_ttype := TT_ASSIGN;
match('=');
if (_ttype <> TT_SKIP) and (pCreate = true) then
begin
_token := makeToken( _ttype);
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
end;
ReturnToken := _token;
end;
// ============================================================================
// mSTRING
// ============================================================================
procedure TTokenLexer.mSTRING( pCreate: boolean);
var
_begin: integer;
_save: integer;
_token: IToken;
_ttype: integer;
begin
_begin := Length( TokenText) +1;
_token := nil;
_ttype := TT_STRING;
match('"');
while(true) do
begin
if (( LA(1) in [#1..'!','#'..#255])) then
begin
matchNot('"');
end
else
break;
end;
match('"');
if (_ttype <> TT_SKIP) and (pCreate = true) then
begin
_token := makeToken( _ttype);
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
end;
ReturnToken := _token;
end;
// ============================================================================
// mDIGIT
// ============================================================================
procedure TTokenLexer.mDIGIT( pCreate: boolean);
var
_begin: integer;
_save: integer;
_token: IToken;
_ttype: integer;
begin
_begin := Length( TokenText) +1;
_token := nil;
_ttype := TT_DIGIT;
match( ['0'..'9']);
if (_ttype <> TT_SKIP) and (pCreate = true) then
begin
_token := makeToken( _ttype);
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
end;
ReturnToken := _token;
end;
// ============================================================================
// mXDIGIT
// ============================================================================
procedure TTokenLexer.mXDIGIT( pCreate: boolean);
var
_begin: integer;
_save: integer;
_token: IToken;
_ttype: integer;
begin
_begin := Length( TokenText) +1;
_token := nil;
_ttype := TT_XDIGIT;
if (( LA(1) in ['0'..'9'])) then
begin
match( ['0'..'9']);
end
else if (( LA(1) in ['a'..'f'])) then
begin
match( ['a'..'f']);
end
else if (( LA(1) in ['A'..'F'])) then
begin
match( ['A'..'F']);
end
else
Raise EMismatchedChar.Create( LA(1), ['0'..'9','A'..'F','a'..'f'], InputState.FileName, InputState.Line, InputState.Column);
if (_ttype <> TT_SKIP) and (pCreate = true) then
begin
_token := makeToken( _ttype);
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
end;
ReturnToken := _token;
end;
// ============================================================================
// mID
// ============================================================================
procedure TTokenLexer.mID( pCreate: boolean);
var
_begin: integer;
_save: integer;
_token: IToken;
_ttype: integer;
begin
_begin := Length( TokenText) +1;
_token := nil;
_ttype := TT_ID;
if (( LA(1) in ['a'..'z'])) then
begin
match( ['a'..'z']);
end
else if (( LA(1) in ['A'..'Z'])) then
begin
match( ['A'..'Z']);
end
else
Raise EMismatchedChar.Create( LA(1), ['A'..'Z','a'..'z'], InputState.FileName, InputState.Line, InputState.Column);
while(true) do
begin
if (( LA(1) in ['a'..'z'])) then
begin
match( ['a'..'z']);
end
else if (( LA(1) in ['A'..'Z'])) then
begin
match( ['A'..'Z']);
end
else if (( LA(1) in ['_'])) then
begin
match('_');
end
else if (( LA(1) in ['0'..'9'])) then
begin
match( ['0'..'9']);
end
else
break;
end;
if (_ttype <> TT_SKIP) and (pCreate = true) then
begin
_token := makeToken( _ttype);
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
end;
ReturnToken := _token;
end;
// ============================================================================
// mINT
// ============================================================================
procedure TTokenLexer.mINT( pCreate: boolean);
var
_begin: integer;
_cnt_15: integer;
_save: integer;
_token: IToken;
_ttype: integer;
begin
_begin := Length( TokenText) +1;
_token := nil;
_ttype := TT_INT;
_cnt_15 := 0;
while(true) do
begin
if (( LA(1) in ['0'..'9'])) then
begin
mDIGIT(false);
end
else
begin
if _cnt_15 >= 1 then
break
else
Raise EMismatchedChar.Create( LA(1), ['0'..'9'], InputState.FileName, InputState.Line, InputState.Column);
end;
INC(_cnt_15);
end;
if (_ttype <> TT_SKIP) and (pCreate = true) then
begin
_token := makeToken( _ttype);
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
end;
ReturnToken := _token;
end;
// ============================================================================
// mWS
// ============================================================================
procedure TTokenLexer.mWS( pCreate: boolean);
var
_begin: integer;
_save: integer;
_token: IToken;
_ttype: integer;
begin
_begin := Length( TokenText) +1;
_token := nil;
_ttype := TT_WS;
if (( LA(1) in [#13]) and (LA(2) in [#10])) then
begin
match(#13);
match(#10);
newLine;
end
else if (( LA(1) in [' '])) then
begin
match(' ');
end
else if (( LA(1) in [#9])) then
begin
match(#9);
end
else if (( LA(1) in [#13])) then
begin
match(#13);
newLine;
end
else if (( LA(1) in [#10])) then
begin
match(#10);
newLine;
end
else
Raise EMismatchedChar.Create( LA(1), [#9..#10,#13,' '], InputState.FileName, InputState.Line, InputState.Column);
_ttype := TT_SKIP;
if (_ttype <> TT_SKIP) and (pCreate = true) then
begin
_token := makeToken( _ttype);
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
end;
ReturnToken := _token;
end;
// ============================================================================
// mSLCOMMENT
// ============================================================================
procedure TTokenLexer.mSLCOMMENT( pCreate: boolean);
var
_begin: integer;
_save: integer;
_token: IToken;
_ttype: integer;
begin
_begin := Length( TokenText) +1;
_token := nil;
_ttype := TT_SLCOMMENT;
match('//');
while(true) do
begin
if (( LA(1) in [#1..#9,#11..#12,#14..#255])) then
begin
match( [#1..#9,#11..#12,#14..#255]);
end
else
break;
end;
if (( LA(1) in [#13]) and (LA(2) in [#10])) then
begin
match(#13);
match(#10);
newLine;
end
else if (( LA(1) in [#13])) then
begin
match(#13);
newLine;
end
else if (( LA(1) in [#10])) then
begin
match(#10);
newLine;
end
else
Raise EMismatchedChar.Create( LA(1), [#10,#13], InputState.FileName, InputState.Line, InputState.Column);
_ttype := TT_SKIP;
if (_ttype <> TT_SKIP) and (pCreate = true) then
begin
_token := makeToken( _ttype);
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
end;
ReturnToken := _token;
end;
// ============================================================================
// mMLCOMMENT
// ============================================================================
procedure TTokenLexer.mMLCOMMENT( pCreate: boolean);
var
_begin: integer;
_save: integer;
_token: IToken;
_ttype: integer;
begin
_begin := Length( TokenText) +1;
_token := nil;
_ttype := TT_MLCOMMENT;
match('(*');
while(true) do
begin
// non-greedy exit test
if( LA(1) in ['*']) and (LA(2) in [')']) then
break;
if (( LA(1) in [#13]) and (LA(2) in [#10])) then
begin
match(#13);
match(#10);
newLine;
end
else if (( LA(1) in [#13])) then
begin
match(#13);
newLine;
end
else if (( LA(1) in [#10])) then
begin
match(#10);
newLine;
end
else if (( LA(1) in [#1..#9,#11..#12,#14..#255])) then
begin
match( [#1..#9,#11..#12,#14..#255]);
end
else
break;
end;
match('*)');
_ttype := TT_SKIP;
if (_ttype <> TT_SKIP) and (pCreate = true) then
begin
_token := makeToken( _ttype);
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
end;
ReturnToken := _token;
end;
// ----------------------------------------------------------------------------
// NextToken
// ----------------------------------------------------------------------------
function TTokenLexer.NextToken : IToken;
var
_first : TCharSet;
begin
_first := [#9..#10,#13,' ','"','('..')','/'..'9','=','A'..'Z','a'..'z'];
while( true) do
begin
ResetText;
try
if (( LA(1) in ['(']) and (LA(2) in ['*'])) then
begin
mMLCOMMENT(true);
result := ReturnToken;
end
else if (( LA(1) in ['('])) then
begin
mLPAREN(true);
result := ReturnToken;
end
else if (( LA(1) in [')'])) then
begin
mRPAREN(true);
result := ReturnToken;
end
else if (( LA(1) in ['='])) then
begin
mASSIGN(true);
result := ReturnToken;
end
else if (( LA(1) in ['"'])) then
begin
mSTRING(true);
result := ReturnToken;
end
else if (( LA(1) in ['A'..'Z','a'..'z'])) then
begin
mID(true);
result := ReturnToken;
end
else if (( LA(1) in ['0'..'9'])) then
begin
mINT(true);
result := ReturnToken;
end
else if (( LA(1) in [#9..#10,#13,' '])) then
begin
mWS(true);
result := ReturnToken;
end
else if (( LA(1) in ['/'])) then
begin
mSLCOMMENT(true);
result := ReturnToken;
end
else
begin
if LA(1) = EOF_CHAR then
begin
uponEof;
result := TToken.Create(TT_EOF);
end
else
Raise EMismatchedChar.Create(LA(1), _first, InputState.FileName, InputState.Line, InputState.Column);
end;
// --------------------------------------------------------------
// If we found a SKIP token, then try again...
// --------------------------------------------------------------
if result = nil then
continue;
// --------------------------------------------------------------
// Now we have a valid token, so exit the function
// --------------------------------------------------------------
break;
except
Raise;
end;
end;
end;
end.
@@ -0,0 +1,26 @@
// ============================================================================
// This file is generated by the Delphi Parser Generator.
// ----------------------------------------------------------------------------
// DPG version: 2.1.0.0r
// Grammar: dpglib.tokenLexer.g
// ============================================================================
unit dpglib.TokenLexerTokens;
interface
const
TT_ID = 10;
TT_STRING = 7;
TT_EOF = 1;
TT_XDIGIT = 9;
TT_SLCOMMENT = 13;
TT_ASSIGN = 6;
TT_WS = 12;
TT_LPAREN = 4;
TT_RPAREN = 5;
TT_DIGIT = 8;
TT_MLCOMMENT = 14;
TT_INT = 11;
implementation
end.
@@ -0,0 +1,14 @@
// $Delphi Parser Generator: dpglib.tokenLexer.g -> dpglib.tokenLexer.gTokens.txt$
TTokenLexer
TT_ID=10
TT_STRING=7
TT_EOF=1
TT_XDIGIT=9
TT_SLCOMMENT=13
TT_ASSIGN=6
TT_WS=12
TT_LPAREN=4
TT_RPAREN=5
TT_DIGIT=8
TT_MLCOMMENT=14
TT_INT=11
+87
View File
@@ -0,0 +1,87 @@
unit dpglib.TokenParser;
uses
{
dpglib.Types;
dpglib.StringSymbol;
dpglib.TokenSymbol;
}
parser TTokenParser;
options
{
importVocab = dpglib.TokenLexer;
k = 3;
}
tokenFile [tm:ITokenManager]
:
name: ID
(tokenLine[tm])*
;
tokenLine [tm:ITokenManager]
local
{
t : IToken;
s : IToken;
v : integer;
sl: IStringSymbol;
ts: ITokenSymbol;
x : AnsiString;
}
: {
t := nil;
s := nil;
}
( s1: STRING { s := s1; }
| lab: ID { t := lab; }
ASSIGN
s2: STRING { s := s2; }
| id: ID { t := id; }
LPAREN
para: STRING
RPAREN
| id2: ID { t := id2; }
)
ASSIGN
i: INT {
v := StrToIntDef( i.TokenText, -1);
if s <> nil then
begin
ts := TStringSymbol.Create( s.TokenText);
ts.TokenType := v;
tm.Define(ts);
if t <> nil then
begin
ts := tm.TokenSymbol[s.TokenText];
ts.QueryInterface( IStringSymbol, sl);
sl.Lbl := t.TokenText;
tm.MapToTokenSymbol( t.TokenText, sl);
end;
end
else if t <> nil then
begin
x := Copy( t.TokenText, 4, Length( t.TokenText)-3);
ts := TTokenSymbol.Create( x);
ts.TokenType := v;
tm.Define( ts);
if para <> nil then
begin
ts := tm.TokenSymbol[ t.TokenText];
ts.Paraphrase := para.TokenText;
end;
end;
}
;
+161
View File
@@ -0,0 +1,161 @@
// ============================================================================
// This file is generated by the Delphi Parser Generator.
// ----------------------------------------------------------------------------
// DPG version: 2.1.0.0r
// Grammar: dpglib.tokenParser.g
// ============================================================================
unit dpglib.TokenParser;
interface
uses
System.Classes,
dpglib.StringSymbol,
dpglib.TokenParserTokens,
dpglib.TokenSymbol,
dpglib.Types,
dpgrtl.llkparser,
dpgrtl.types,
System.SysUtils;
type
// =========================================================================
// Class TTokenParser declaration
// =========================================================================
TTokenParser = class( TLLkParser)
public // Public grammar rules
procedure tokenFile ( tm:ITokenManager);
procedure tokenLine ( tm:ITokenManager);
end;
implementation
uses
dpgrtl.exception,
dpgrtl.token;
// ============================================================================
// tokenFile
// ============================================================================
procedure TTokenParser.tokenFile( tm:ITokenManager);
var
name: IToken;
begin
name := LT(1);
match(TT_ID);
while(true) do
begin
if (( LA(1) in [TT_STRING,TT_ID])) then
begin
tokenLine(tm);
end
else
break;
end;
end;
// ============================================================================
// tokenLine
// ============================================================================
procedure TTokenParser.tokenLine( tm:ITokenManager);
var
i: IToken;
id: IToken;
id2: IToken;
lab: IToken;
para: IToken;
s1: IToken;
s2: IToken;
t : IToken;
s : IToken;
v : integer;
sl: IStringSymbol;
ts: ITokenSymbol;
x : AnsiString;
begin
t := nil;
s := nil;
if (( LA(1) in [TT_STRING])) then
begin
s1 := LT(1);
match(TT_STRING);
s := s1;
end
else if (( LA(1) in [TT_ID]) and (LA(2) in [TT_ASSIGN]) and (LA(3) in [TT_STRING])) then
begin
lab := LT(1);
match(TT_ID);
t := lab;
match(TT_ASSIGN);
s2 := LT(1);
match(TT_STRING);
s := s2;
end
else if (( LA(1) in [TT_ID]) and (LA(2) in [TT_LPAREN])) then
begin
id := LT(1);
match(TT_ID);
t := id;
match(TT_LPAREN);
para := LT(1);
match(TT_STRING);
match(TT_RPAREN);
end
else if (( LA(1) in [TT_ID]) and (LA(2) in [TT_ASSIGN]) and (LA(3) in [TT_INT])) then
begin
id2 := LT(1);
match(TT_ID);
t := id2;
end
else
Raise EMismatchedToken.Create( LT(1), [TT_STRING,TT_ID], InputState.FileName);
match(TT_ASSIGN);
i := LT(1);
match(TT_INT);
v := StrToIntDef( i.TokenText, -1);
if s <> nil then
begin
ts := TStringSymbol.Create( s.TokenText);
ts.TokenType := v;
tm.Define(ts);
if t <> nil then
begin
ts := tm.TokenSymbol[s.TokenText];
ts.QueryInterface( IStringSymbol, sl);
sl.Lbl := t.TokenText;
tm.MapToTokenSymbol( t.TokenText, sl);
end;
end
else if t <> nil then
begin
x := Copy( t.TokenText, 4, Length( t.TokenText)-3);
ts := TTokenSymbol.Create( x);
ts.TokenType := v;
tm.Define( ts);
if para <> nil then
begin
ts := tm.TokenSymbol[ t.TokenText];
ts.Paraphrase := para.TokenText;
end;
end;
end;
end.
@@ -0,0 +1,26 @@
// ============================================================================
// This file is generated by the Delphi Parser Generator.
// ----------------------------------------------------------------------------
// DPG version: 2.1.0.0r
// Grammar: dpglib.tokenParser.g
// ============================================================================
unit dpglib.TokenParserTokens;
interface
const
TT_ID = 10;
TT_STRING = 7;
TT_EOF = 1;
TT_SLCOMMENT = 13;
TT_XDIGIT = 9;
TT_ASSIGN = 6;
TT_WS = 12;
TT_LPAREN = 4;
TT_RPAREN = 5;
TT_DIGIT = 8;
TT_MLCOMMENT = 14;
TT_INT = 11;
implementation
end.
@@ -0,0 +1,14 @@
// $Delphi Parser Generator: dpglib.tokenParser.g -> dpglib.tokenParser.gTokens.txt$
TTokenParser
TT_ID=10
TT_STRING=7
TT_EOF=1
TT_SLCOMMENT=13
TT_XDIGIT=9
TT_ASSIGN=6
TT_WS=12
TT_LPAREN=4
TT_RPAREN=5
TT_DIGIT=8
TT_MLCOMMENT=14
TT_INT=11
+349
View File
@@ -0,0 +1,349 @@
unit z.dpglib.DpgLexer;
lexer TDpgLexer;
options
{
testLiterals = false;
k = 2;
}
tokens
{
"unit";
"uses";
"const";
"type";
"lexer";
"parser";
"options";
"tokens";
"memberdecl";
"memberdef";
"private";
"protected";
"public";
"returns";
"local";
"except";
"finally";
SEMPRED;
USES;
OPTIONS;
TOKENS;
}
// ----------------------------------------------------------------------------
// Simple tokens
// ----------------------------------------------------------------------------
LPAREN: '(';
RPAREN: ')';
RCURLY: '}';
COLON: ':';
SEMI: ';';
COMMA: ',';
ASSIGN: '=';
IMPLIES: "=>";
QUEST: '?';
PLUS: '+';
STAR: '*';
AT: '@';
NOT: '~';
OR: '|';
BANG: '!';
WILDCARD: '.';
RANGE: "..";
// ----------------------------------------------------------------------------
// Character literal
// ----------------------------------------------------------------------------
CHARLIT
: '\''! (ESC | ~'\'') '\''! ;
// ----------------------------------------------------------------------------
// String literal
// ----------------------------------------------------------------------------
STRINGLIT
: '"' (ESC | ~'"')* '"' ;
// ----------------------------------------------------------------------------
// Integer
// ----------------------------------------------------------------------------
INTEGER
local
{
i: integer;
v: integer;
}
:
(
DNUMBER
{
v := 0;
for i:=1 to Length( TokenText) do
begin
v := v * 10 + ord( TokenText[i]) - ord('0');
end;
TokenText := IntToStr( v);
}
|
XNUMBER
{
v := 0;
for i:=1 to Length( TokenText) do
begin
case TokenText[i] of
'0'..'9': v := v * 16 + ord(TokenText[i]) - ord('0');
'a'..'z': v := v * 16 + ord(TokenText[i]) - ord('a');
'A'..'Z': v := v * 16 + ord(TokenText[i]) - ord('A');
end;
end;
TokenText := IntToStr( v);
}
)
;
// ----------------------------------------------------------------------------
// Argument action
// ----------------------------------------------------------------------------
ARGACTION
:
'['!
(
options
{
generateAmbigWarnings = false;
}
: '\r' '\n' { newLine; }
| '\r' { newLine; }
| '\n' { newLine; }
| ~']'
)*
']'!
;
// ----------------------------------------------------------------------------
// Action
// ----------------------------------------------------------------------------
ACTION
:
'{'
(
options
{
generateAmbigWarnings = false;
}
: '\r' '\n' { newLine; }
| '\r' { newLine; }
| '\n' { newLine; }
| ~'}'
)*
'}'
( '?'! { _ttype := TT_SEMPRED; } )?
;
// ----------------------------------------------------------------------------
// Token ref
// ----------------------------------------------------------------------------
TOKENREF
options
{
testLiterals = true;
}
: 'A'..'Z' ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')* ;
// ----------------------------------------------------------------------------
// Rule ref
// ----------------------------------------------------------------------------
RULEREF
local
{
t: integer;
}
:
t = INT_RULEREF { _ttype := t; }
(
{t = LT_uses}? WS_LOOP ('{' { _ttype := TT_USES; } )?
| {t = LT_options}? WS_LOOP ('{' { _ttype := TT_OPTIONS; } )?
| {t = LT_tokens}? WS_LOOP ('{' { _ttype := TT_TOKENS; } )?
)?
;
// ----------------------------------------------------------------------------
// Internal rule ref
// ----------------------------------------------------------------------------
protected
INT_RULEREF returns [integer]
{
_ttype := TT_RULEREF;
}
: 'a'..'z' ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*
{
result := TestLiteral( _ttype);
}
;
// ----------------------------------------------------------------------------
// COMMENT
// ----------------------------------------------------------------------------
COMMENT
: SLCOMMENT { _ttype := TT_SKIP; }
| MLCOMMENT1 { _ttype := TT_SKIP; }
| MLCOMMENT2 { _ttype := TT_SKIP; }
;
// ----------------------------------------------------------------------------
// SLCOMMENT
// ----------------------------------------------------------------------------
protected
SLCOMMENT
:
"//"
( ~( '\r' | '\n') )*
(
options
{
generateAmbigWarnings = false;
}
: '\r' '\n' { newLine; }
| '\r' { newLine; }
| '\n' { newLine; }
)
;
// ============================================================================
// Multi line comment version 1
// Nested comments aren't allowed!
// ============================================================================
protected
MLCOMMENT1
:
"(*"
(
options
{
greedy = false;
generateAmbigWarnings = false;
}
: '\r' '\n' { newLine; }
| '\r' { newLine; }
| '\n' { newLine; }
| .
)*
"*)"
;
// ============================================================================
// Multi line comment version 2
// Nested comments aren't allowed!
// ============================================================================
protected
MLCOMMENT2
:
"/*"
(
options
{
greedy = false;
generateAmbigWarnings = false;
}
: '\r' '\n' { newLine; }
| '\r' { newLine; }
| '\n' { newLine; }
| .
)*
"*/"
;
// ----------------------------------------------------------------------------
// Numbers
// ----------------------------------------------------------------------------
protected DNUMBER: '0'..'9' (DDIGIT)*;
protected XNUMBER: '$'! (XDIGIT)+;
// ----------------------------------------------------------------------------
// Digits
// ----------------------------------------------------------------------------
protected DDIGIT: '0'..'9';
protected XDIGIT: '0'..'9' | 'a'..'f' | 'A'..'F';
// ----------------------------------------------------------------------------
// WS
// ----------------------------------------------------------------------------
WS
:
(
options
{
generateAmbigWarnings = false;
}
: ' '
| '\t' { tab; }
| '\r' '\n' { newLine; }
| '\r' { newLine; }
| '\n' { newLine; }
)
{
_ttype := TT_SKIP;
}
;
// ----------------------------------------------------------------------------
// WS_LOOP
// ----------------------------------------------------------------------------
protected
WS_LOOP
:
(
options
{
greedy = true;
}
: WS
| COMMENT
)*
;
// ----------------------------------------------------------------------------
// Esc
// ----------------------------------------------------------------------------
protected
ESC
local
{
number: AnsiString;
}
:
'\\'!
(
'r' { TokenText[ Length( TokenText)] := AnsiChar(13); }
| 'n' { TokenText[ Length( TokenText)] := AnsiChar(10); }
| 't' { TokenText[ Length( TokenText)] := AnsiChar(9); }
| '\\'
| '\''
| '"'
| 'x' d1:XDIGIT! d2:XDIGIT!
{
number := '$' + d1.TokenText + d2.TokenText;
TokenText[ Length( TokenText)] := AnsiChar( StrToInt( number));
}
)
;
+798
View File
@@ -0,0 +1,798 @@
unit z.dpglib.DpgParser;
uses
{
z.dpglib.types;
}
parser TDpgParser;
options
{
defaultErrorHandler = false;
importVocab = z.dpglib.DpgLexer;
exportVocab = z.dpglib.DpgParser;
k = 2;
}
memberdecl
{
protected
fGrammarMaker : IGrammarBehavior;
fTool : ITool;
fNesting : integer;
fExchangeDir : AnsiString;
fGrammarFile : AnsiString;
fGrammarUnit : AnsiString;
private
function lastInRule : boolean;
procedure checkEndRule( pToken: IToken);
public
constructor Create( pParserState : IParserState;
pGrammarMaker : IGrammarBehavior;
pTool : ITool;
pExchangeDir : AnsiString); overload;
constructor Create( pTokenBuffer : ITokenBuffer;
pGrammarMaker : IGrammarBehavior;
pTool : ITool;
pExchangeDir : AnsiString); overload;
constructor Create( pTokenStream : ITokenStream;
pGrammarMaker : IGrammarBehavior;
pTool : ITool;
pExchangeDir : AnsiString); overload;
destructor Destroy; override;
}
// ----------------------------------------------------------------------------
// grammar
// ----------------------------------------------------------------------------
grammar
local
{
unitName: IToken;
}
:
"unit" "[" unitName=qualifiedId {fGrammarUnit := unitName.TokenText;} SEMI
(usesDecl)?
(constDecl)?
(typeDecl)?
classDecl
{fGrammarMaker.endGrammar;}
;
// ----------------------------------------------------------------------------
// usesDecl
// ----------------------------------------------------------------------------
usesDecl
:
USES
(
// tr:TOKENREF SEMI {fGrammarMaker.defineUses( tr);}
// | rr:RULEREF SEMI {fGrammarMaker.defineUses( rr);}
qualifiedUsesName SEMI
)*
RCURLY
;
qualifiedUsesName
local
{
id: AnsiString;
}
: ( r:TOKENREF | r:RULEREF ) { id := r.TokenText; }
( WILDCARD
( r:TOKENREF | r:RULEREF) { id := id +'.'+ r.TokenText; }
)*
{
fGrammarMaker.defineUses(id);
}
;
// ----------------------------------------------------------------------------
// constDecl
// ----------------------------------------------------------------------------
constDecl
:
"const"
a:ACTION {fGrammarMaker.RefConstAction( a);}
;
// ----------------------------------------------------------------------------
// typeDecl
// ----------------------------------------------------------------------------
typeDecl
:
"type"
a:ACTION {fGrammarMaker.RefTypeAction( a);}
;
// ----------------------------------------------------------------------------
// classDecl
// ----------------------------------------------------------------------------
classDecl
local
{
grType : integer;
grObject : IToken;
grSuper : IToken;
}
{
grObject := nil;
grSuper := nil;
}
:
// ------------------------------------------------------------
// Determine parser type
// ------------------------------------------------------------
( "lexer" { grType := 0; }
| "parser" { grType := 1; }
)
// ------------------------------------------------------------
// get class name
// ------------------------------------------------------------
grObject = id
// ------------------------------------------------------------
// get superclass name
// ------------------------------------------------------------
// (
// LPAREN
// grSuper=id
// RPAREN
// )?
SEMI
// ------------------------------------------------------------
// Start the grammar
// ------------------------------------------------------------
{
// ---------------------------------------------------------
// Now we have enough information to start the grammar.
// ---------------------------------------------------------
case grType of
0: fGrammarMaker.StartLexer( InputState.FileName,
grObject,
grSuper);
1: fGrammarMaker.StartParser( InputState.FileName,
grObject,
grSuper);
2: fGrammarMaker.StartTreeWalker( InputState.FileName,
grObject,
grSuper);
end;
fGrammarMaker.defineGrammarUnit( fGrammarUnit);
}
// ------------------------------------------------------------
// Process optional class "options {...}" clause
// ------------------------------------------------------------
(classOptions)?
// ------------------------------------------------------------
// Process optional class "tokens {...}" clause
// But only for lexers.
// ------------------------------------------------------------
( {grType=0}? classTokens)?
// ------------------------------------------------------------
// Process optional class "memberDecl {...}" clause
// ------------------------------------------------------------
(classMemberDecl)?
// ------------------------------------------------------------
// Well, the rules
// ------------------------------------------------------------
rules
// ------------------------------------------------------------
// Process optional class "memberDecl {...}" clause
// ------------------------------------------------------------
(classMemberDef)?
;
// ----------------------------------------------------------------------------
// classOptions
// ----------------------------------------------------------------------------
classOptions
local
{
optName : IToken;
optValue : IToken;
}
:
OPTIONS
(
optName = id
ASSIGN
optValue = optionValue
SEMI
{fGrammarMaker.setGrammarOption( optName, optValue);}
)*
RCURLY
;
// ----------------------------------------------------------------------------
// classTokens
// ----------------------------------------------------------------------------
classTokens
:
TOKENS
(
{
tokenName := nil;
tokenString := nil;
}
(
tokenName: TOKENREF (ASSIGN tokenString:STRINGLIT)?
| tokenString: STRINGLIT
)
SEMI
{fGrammarMaker.defineToken( tokenName, tokenString);}
)*
RCURLY
;
// ----------------------------------------------------------------------------
// classMemberDecl
// ----------------------------------------------------------------------------
classMemberDecl
:
"memberDecl"
memberDecl:ACTION
{fGrammarMaker.refMemberDecl(memberDecl);}
;
// ----------------------------------------------------------------------------
// classMemberDef
// ----------------------------------------------------------------------------
classMemberDef
:
"memberDef"
memberDef:ACTION
{fGrammarMaker.refMemberDef(memberDef);}
;
// ----------------------------------------------------------------------------
// rules
// ----------------------------------------------------------------------------
rules
:
(rule)*
;
// ----------------------------------------------------------------------------
// ruleExceptionBlock
// ----------------------------------------------------------------------------
ruleExceptionBlock
:
t:"except" a:ACTION { fGrammarMaker.RefRuleExHandler( t, a); }
| t:"finally" a:ACTION { fGrammarMaker.RefRuleExHandler( t, a); }
;
// ----------------------------------------------------------------------------
// ruleExceptionBlock
// ----------------------------------------------------------------------------
altExceptionBlock
:
t:"except" a:ACTION { fGrammarMaker.RefAltExHandler( t, a); }
| t:"finally" a:ACTION { fGrammarMaker.RefAltExHandler( t, a); }
;
// ----------------------------------------------------------------------------
// rule
// ----------------------------------------------------------------------------
rule
local
{
access : AnsiString;
ag : integer;
returns : IToken;
name : IToken;
}
{
access := 'public';
args := nil;
name := nil;
ag := AUTOGEN_NONE;
}
:
// ------------------------------------------------------------
// Parse rule scope
// ------------------------------------------------------------
( "public" { access := 'public'; }
| "protected" { access := 'protected'; }
| "private" { access := 'private'; }
)?
// ------------------------------------------------------------
// Parse rule name
// ------------------------------------------------------------
name=id
// ------------------------------------------------------------
// Parse optional BANG operator
// ------------------------------------------------------------
// ( BANG { ag := AUTOGEN_BANG;} )?
// ------------------------------------------------------------
// Optional arguments
// ------------------------------------------------------------
( args:ARGACTION)?
// ------------------------------------------------------------
// Optional return type
// ------------------------------------------------------------
( "returns" ret:ARGACTION)?
// ------------------------------------------------------------
// Now start the rule definition
// ------------------------------------------------------------
{
fGrammarMaker.defineRuleName( name, access, true, '');
if args <> nil then
fGrammarMaker.refArgAction( args);
if ret <> nil then
fGrammarMaker.refReturnAction( ret);
}
// ------------------------------------------------------------
// Optional rule options
// ------------------------------------------------------------
(ruleOptions)?
// ------------------------------------------------------------
// Optional rule local variable declarations
// ------------------------------------------------------------
(
"local"
locals:ACTION
{fGrammarMaker.refRuleLocals( locals);}
)?
// ------------------------------------------------------------
// Optional rule init action
// ------------------------------------------------------------
(
initAction:ACTION
{fGrammarMaker.refInitAction( initAction);}
)?
// ------------------------------------------------------------
// Rule block
// ------------------------------------------------------------
COLON
block
SEMI
// ------------------------------------------------------------
// Optional exception handler
// ------------------------------------------------------------
( ruleExceptionBlock)?
// ------------------------------------------------------------
// Finish the rule
// ------------------------------------------------------------
{ fGrammarMaker.endRule('');}
;
// ----------------------------------------------------------------------------
// block
// ----------------------------------------------------------------------------
block
{
INC( fNesting);
}
: alternative (OR alternative)* {DEC(fNesting);}
;
// ----------------------------------------------------------------------------
// alternative
// ----------------------------------------------------------------------------
alternative
local
{
autoGen : boolean;
}
{
autoGen := true;
}
:
// (BANG {autoGen := false;})?
{fGrammarMaker.beginAlt( autoGen);}
(elem)*
(altExceptionBlock)?
{fGrammarMaker.endAlt;}
;
// ----------------------------------------------------------------------------
// elem
// ----------------------------------------------------------------------------
elem
: element
;
// ----------------------------------------------------------------------------
// element
// ----------------------------------------------------------------------------
element
local
{
assignId : IToken;
assignLabel : IToken;
autoGen : integer;
}
{
assignId := nil;
assignLabel := nil;
autoGen := AUTOGEN_NONE;
}
:
(
assignId=id ASSIGN
(assignLabel=id COLON {checkEndRule(assignLabel);})?
(
ruleRef:RULEREF (args:ARGACTION)? (ag:BANG {autoGen := AUTOGEN_BANG;})?
{fGrammarMaker.refRule( assignId, ruleRef, assignLabel, args, autoGen);}
|
tokenRef:TOKENREF (args:ARGACTION)?
{fGrammarMaker.refToken( assignId, tokenRef, assignLabel, args, false, autoGen, lastInRule);}
)
)
|
(assignLabel=id COLON {checkEndRule(assignLabel);})?
(
ruleRef:RULEREF (args:ARGACTION)? (ag:BANG {autoGen := AUTOGEN_BANG;})?
{fGrammarMaker.refRule( assignId, ruleRef, assignLabel, args, autoGen);}
| range[assignLabel]
| terminal[assignLabel]
| NOT (notTerminal[assignLabel] | ebnf[ assignLabel, true])
| ebnf[ assignLabel, false]
)
|
action:ACTION
{fGrammarMaker.refAction( action);}
|
semPred:SEMPRED
{fGrammarMaker.refSemPred( semPred);}
;
// ----------------------------------------------------------------------------
// range
// ----------------------------------------------------------------------------
range [pTokenLabel: IToken]
local
{
autoGen: integer;
}
{
autoGen := AUTOGEN_NONE;
}
:
crLeft:CHARLIT
RANGE
crRight:CHARLIT
(BANG {autoGen := AUTOGEN_BANG;} )?
{fGrammarMaker.refCharRange( crLeft, crRight, pTokenLabel, autoGen, lastInRule);}
|
(trLeft:TOKENREF | trLeft:STRINGLIT)
RANGE
(trRight:TOKENREF | trRight:STRINGLIT)
autoGen=astTypeSpec
{fGrammarMaker.refTokenRange( trLeft, trRight, pTokenLabel, autoGen, lastInRule);}
;
// ----------------------------------------------------------------------------
// terminal
// ----------------------------------------------------------------------------
terminal [pTokenLabel: IToken]
local
{
autoGen : integer;
}
{
autoGen := AUTOGEN_NONE;
aa := nil;
}
:
cl:CHARLIT
(BANG {autoGen := AUTOGEN_BANG;} )?
{fGrammarMaker.refCharLiteral( cl, pTokenLabel, false, autoGen, lastInRule);}
|
tr:TOKENREF
autoGen=astTypeSpec
(aa:ARGACTION)?
{fGrammarMaker.refToken( nil, tr, pTokenLabel, aa, false, autoGen, lastInRule);}
|
sl:STRINGLIT
autoGen=astTypeSpec
{fGrammarMaker.refStringLiteral( sl, pTokenLabel, autoGen, lastInRule);}
|
wc:WILDCARD
autogen=astTypeSpec
{fGrammarMaker.refWildCard( wc, pTokenLabel, autoGen);}
;
// ----------------------------------------------------------------------------
// notTerminal
// ----------------------------------------------------------------------------
notTerminal [pTokenLabel: IToken]
local
{
autoGen : integer;
}
{
autoGen := AUTOGEN_NONE;
}
:
cl:CHARLIT
(BANG {autoGen := AUTOGEN_BANG;} )?
{fGrammarMaker.refCharLiteral( cl, pTokenLabel, true, autoGen, lastInRule);}
|
tr:TOKENREF
autoGen=astTypeSpec
{fGrammarMaker.refToken( nil, tr, pTokenLabel, nil, true, autoGen, lastInRule);}
;
// ----------------------------------------------------------------------------
// ebnf
// ----------------------------------------------------------------------------
ebnf [pTokenLabel: IToken; pTokenNot: boolean]
:
lp:LPAREN
{fGrammarMaker.beginSubrule( pTokenLabel, lp, pTokenNot);}
(
// ---------------------------------------------------------
// 2nd alt and optional branch ambig due to linear approx
// LL(2) issue. COLON ACTION matched correctly in 2nd alt.
// ---------------------------------------------------------
options
{
warnWhenFollowAmbig = false;
}
:
subRuleOptions
(aa:ACTION {fGrammarMaker.refInitAction(aa);} )?
COLON
|
aa:ACTION {fGrammarMaker.refInitAction(aa);}
COLON
)?
block
RPAREN
(
( QUEST { fGrammarMaker.optionalSubrule; }
| STAR { fGrammarMaker.zeroOrMoreSubrule; }
| PLUS { fGrammarMaker.oneOrMoreSubrule; }
| AT { fGrammarMaker.nmSubrule; }
LPAREN
(
m:INTEGER { fGrammarMaker.refRangeLow( StrToInt(m.TokenText)); }
(
COMMA { fGrammarMaker.refRangeHigh( maxint); }
(
n:INTEGER { fGrammarMaker.refRangeHigh(StrToInt(n.TokenText)); }
)?
)?
|
COMMA
n:INTEGER { fGrammarMaker.refRangeHigh(StrToInt(n.TokenText)); }
)
RPAREN
| IMPLIES {fGrammarMaker.synPred; }
)?
// ( BANG {fGrammarMaker.noASTSubrule;} )?
)
{fGrammarMaker.endSubRule;}
;
// ----------------------------------------------------------------------------
// optionValue
// ----------------------------------------------------------------------------
optionValue returns [IToken]
:
result=qualifiedId
| result:STRINGLIT
| result:CHARLIT
| result:INTEGER
;
// ----------------------------------------------------------------------------
// subruleOptions
// ----------------------------------------------------------------------------
subruleOptions
local
{
optName : IToken;
optValue : IToken;
}
:
OPTIONS
(
optName = id
ASSIGN
optValue = optionValue
SEMI
{fGrammarMaker.setSubruleOption( optName, optValue);}
)*
RCURLY
;
// ----------------------------------------------------------------------------
// ruleOptions
// ----------------------------------------------------------------------------
ruleOptions
local
{
optName : IToken;
optValue : IToken;
}
:
OPTIONS
(
optName = id
ASSIGN
optValue = optionValue
SEMI
{fGrammarMaker.setRuleOption( optName, optValue);}
)*
RCURLY
;
// ----------------------------------------------------------------------------
// astTypeSpec
// ----------------------------------------------------------------------------
astTypeSpec returns [integer]
{
result := AUTOGEN_NONE;
}
:
(BANG {result := AUTOGEN_BANG;})?
;
// ----------------------------------------------------------------------------
// qualifiedId
// ----------------------------------------------------------------------------
qualifiedId returns [IToken]
local
{
buf : AnsiString;
a : IToken;
}
:
a=id { buf := a.TokenText; }
(
WILDCARD a=id { buf := buf + '.' + a.TokenText; }
)*
{
// -----------------------------------------------------------
// Can either TOKENREF or RULEREF. Should really create QID or
// something else instead.
// -----------------------------------------------------------
result := TToken.Create( TT_TOKENREF, buf);
result.TokenLine := a.TokenLine;
result.TokenColumn := a.TokenColumn;
}
;
// ----------------------------------------------------------------------------
// id
// ----------------------------------------------------------------------------
id returns [IToken]
:
result:TOKENREF
| result:RULEREF
;
memberdef
{
// ============================================================================
// Constructor
// ============================================================================
constructor TDpgParser.Create( pParserState : IParserState;
pGrammarMaker : IGrammarBehavior;
pTool : ITool;
pExchangeDir : AnsiString);
begin
inherited Create( pParserState, 2);
fGrammarMaker := pGrammarMaker;
fExchangeDir := pExchangeDir;
fTool := pTool;
fNesting := 0;
end;
// ============================================================================
// Constructor
// ============================================================================
constructor TDpgParser.Create( pTokenBuffer : ITokenBuffer;
pGrammarMaker : IGrammarBehavior;
pTool : ITool;
pExchangeDir : AnsiString);
begin
inherited Create( pTokenBuffer, 2);
fGrammarMaker := pGrammarMaker;
fExchangeDir := pExchangeDir;
fTool := pTool;
fNesting := 0;
end;
// ============================================================================
// Constructor
// ============================================================================
constructor TDpgParser.Create( pTokenStream : ITokenStream;
pGrammarMaker : IGrammarBehavior;
pTool : ITool;
pExchangeDir : AnsiString);
begin
inherited Create( pTokenStream, 2);
fGrammarMaker := pGrammarMaker;
fExchangeDir := pExchangeDir;
fTool := pTool;
fNesting := 0;
end;
// ============================================================================
// Destructor
// ============================================================================
destructor TDpgParser.Destroy;
begin
fGrammarMaker := nil;
fTool := nil;
inherited;
end;
// ============================================================================
// lastInRule
// ============================================================================
function TDpgParser.lastInRule: boolean;
begin
if (fNesting = 0) and (LA(1) in [TT_SEMI, TT_OR])
then result := true
else result := false;
end;
// ============================================================================
// checkEndRule
// ============================================================================
procedure TDpgParser.checkEndRule( pToken: IToken);
begin
if pToken <> nil then
if pToken.TokenColumn = 1 then
fTool.Warning('Did you forget to close the previous rule?',
InputState.FileName,
pToken.TokenLine,
pToken.TokenColumn);
end;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,72 @@
// ============================================================================
// This file is generated by the Delphi Parser Generator.
// ----------------------------------------------------------------------------
// DPG version: 2.0.1.0r
// Grammar: lexer.g
// ============================================================================
unit dpglib.DpgLexerTokens;
interface
const
TT_EOF = 1;
LT_unit = 4;
LT_uses = 5;
LT_const = 6;
LT_type = 7;
LT_lexer = 8;
LT_parser = 9;
LT_options = 10;
LT_tokens = 11;
LT_memberdecl = 12;
LT_memberdef = 13;
LT_private = 14;
LT_protected = 15;
LT_public = 16;
LT_returns = 17;
LT_local = 18;
LT_except = 19;
LT_finally = 20;
TT_SEMPRED = 21;
TT_USES = 22;
TT_OPTIONS = 23;
TT_TOKENS = 24;
TT_LPAREN = 25;
TT_RPAREN = 26;
TT_RCURLY = 27;
TT_COLON = 28;
TT_SEMI = 29;
TT_COMMA = 30;
TT_ASSIGN = 31;
TT_IMPLIES = 32;
TT_QUEST = 33;
TT_PLUS = 34;
TT_STAR = 35;
TT_AT = 36;
TT_NOT = 37;
TT_OR = 38;
TT_BANG = 39;
TT_WILDCARD = 40;
TT_RANGE = 41;
TT_CHARLIT = 42;
TT_STRINGLIT = 43;
TT_INTEGER = 44;
TT_ARGACTION = 45;
TT_ACTION = 46;
TT_TOKENREF = 47;
TT_RULEREF = 48;
TT_INT_RULEREF = 49;
TT_COMMENT = 50;
TT_SLCOMMENT = 51;
TT_MLCOMMENT1 = 52;
TT_MLCOMMENT2 = 53;
TT_DNUMBER = 54;
TT_XNUMBER = 55;
TT_DDIGIT = 56;
TT_XDIGIT = 57;
TT_WS = 58;
TT_WS_LOOP = 59;
TT_ESC = 60;
implementation
end.
@@ -0,0 +1,60 @@
// $Delphi Parser Generator: lexer.g -> lexer.gTokens.txt$
TDpgLexer
TT_EOF=1
LT_unit="unit"=4
LT_uses="uses"=5
LT_const="const"=6
LT_type="type"=7
LT_lexer="lexer"=8
LT_parser="parser"=9
LT_options="options"=10
LT_tokens="tokens"=11
LT_memberdecl="memberdecl"=12
LT_memberdef="memberdef"=13
LT_private="private"=14
LT_protected="protected"=15
LT_public="public"=16
LT_returns="returns"=17
LT_local="local"=18
LT_except="except"=19
LT_finally="finally"=20
TT_SEMPRED=21
TT_USES=22
TT_OPTIONS=23
TT_TOKENS=24
TT_LPAREN=25
TT_RPAREN=26
TT_RCURLY=27
TT_COLON=28
TT_SEMI=29
TT_COMMA=30
TT_ASSIGN=31
TT_IMPLIES=32
TT_QUEST=33
TT_PLUS=34
TT_STAR=35
TT_AT=36
TT_NOT=37
TT_OR=38
TT_BANG=39
TT_WILDCARD=40
TT_RANGE=41
TT_CHARLIT=42
TT_STRINGLIT=43
TT_INTEGER=44
TT_ARGACTION=45
TT_ACTION=46
TT_TOKENREF=47
TT_RULEREF=48
TT_INT_RULEREF=49
TT_COMMENT=50
TT_SLCOMMENT=51
TT_MLCOMMENT1=52
TT_MLCOMMENT2=53
TT_DNUMBER=54
TT_XNUMBER=55
TT_DDIGIT=56
TT_XDIGIT=57
TT_WS=58
TT_WS_LOOP=59
TT_ESC=60