Files
bds.mr.dpg/src.lib/dpglib.GrammarBehavior.pas
T
2026-01-03 18:33:48 +01:00

951 lines
39 KiB
ObjectPascal

unit dpglib.GrammarBehavior;
interface
uses
System.Classes,
dpgrtl.types,
dpglib.Types;
type
TGrammarBehavior = class( TInterfacedObject, IGrammarBehavior)
protected
fGrammar : IGrammar;
fTool : ITool;
fAnalyzer : ILLkAnalyzer;
fUsesList : TStringList;
fIsLexer : boolean;
fIsParser : boolean;
fIsTreeWalker : boolean;
fLexerGrammar : ILexerGrammar;
fParserGrammar : IParserGrammar;
fTreeWalkerGrammar: ITreeWalkerGrammar;
fLanguage : AnsiString;
fExchangeDir : AnsiString;
fConstAction : IToken;
fTypeAction : IToken;
protected
// ------------------------------------------------------------
// _RefRule
// ------------------------------------------------------------
procedure _RefStringLiteral( pLiteral : IToken);
procedure _RefToken( pToken : IToken);
procedure _RefRule( pRuleName : IToken);
public
constructor Create( pTool : ITool;
pAnalyzer : ILLkAnalyzer;
pExchangeDir : AnsiString);
destructor Destroy; override;
public
// ------------------------------------------------------------
// IGrammarBehavior methods
// ------------------------------------------------------------
function Grammar: IGrammar;
procedure AbortGrammar; virtual;
procedure BeginAlt( pDoAST: boolean); virtual; abstract;
procedure BeginExceptionGroup; virtual; abstract;
procedure BeginExceptionSpec( pLabel : IToken); virtual; abstract;
procedure BeginSubRule( pLabel : IToken;
pStart : IToken;
pNot : boolean); virtual; abstract;
procedure BeginTree( pStart : IToken); virtual; abstract;
procedure BeginChildList; virtual; abstract;
procedure DefineGrammarUnit( pUnit : AnsiString); virtual;
procedure DefineRuleName( pRule : IToken;
pAccess : AnsiString;
pRuleAutoGen : boolean;
pDocComment : AnsiString); virtual;
procedure DefineToken( pTokenName : IToken;
pTokenLiteral : IToken); virtual;
procedure DefineUses( pUses : AnsiString); virtual;
procedure EndAlt; virtual; abstract;
procedure EndExceptionGroup; virtual; abstract;
procedure EndExceptionSpec; virtual; abstract;
procedure EndGrammar; virtual; abstract;
procedure EndOptions; virtual;
procedure EndRule( pRuleName : AnsiString); virtual; abstract;
procedure EndSubRule; virtual; abstract;
procedure EndTree; virtual; abstract;
procedure EndChildList; virtual; abstract;
procedure HasError; virtual; abstract;
procedure NoASTSubRule; virtual; abstract;
procedure OneOrMoreSubRule; virtual; abstract;
procedure NMSubRule; virtual; abstract;
procedure OptionalSubRule; virtual; abstract;
procedure refRangeLow( M : integer); virtual; abstract;
procedure refRangeHigh( N : integer); virtual; abstract;
procedure RefAction( pAction : IToken); virtual; abstract;
procedure RefArgAction( pAction : IToken); virtual; abstract;
procedure RefCharLiteral( pLiteral : IToken;
pLabel : IToken;
pInverted : boolean;
pAutoGenType : integer;
pLastInRule : boolean); virtual; abstract;
procedure RefCharRange( pToken1 : IToken;
pToken2 : IToken;
pLabel : IToken;
pAutoGenType : integer;
pLastInRule : boolean); virtual; abstract;
procedure RefConstAction( pConstAction : IToken); virtual;
procedure RefTypeAction( pTypeAction : IToken); virtual;
procedure RefElemOption( pOption : IToken;
pValue : IToken); virtual; abstract;
procedure RefTokenSpecElemOption( pToken : IToken;
pOption : IToken;
pValue : IToken); virtual; abstract;
procedure RefExceptionHandler( pTypeAndName : IToken;
pAction : IToken); virtual; abstract;
procedure RefInitAction( pAction : IToken); virtual; abstract;
procedure RefMemberDecl( pDecl : IToken); virtual;
procedure RefMemberDef( pDef : IToken); virtual;
procedure RefReturnAction( pAction : IToken); virtual; abstract;
procedure RefRule( pAssignId : IToken;
pRuleName : IToken;
pLabel : IToken;
pArguments : IToken;
pAutoGenType : integer); virtual;
procedure RefRuleExHandler( pExHandlerType : IToken;
pExHandlerCode : IToken); virtual; abstract;
procedure RefAltExHandler( pExHandlerType : IToken;
pExHandlerCode : IToken); virtual; abstract;
procedure RefRuleLocals( pLocals : IToken); virtual; abstract;
procedure RefSemPred( pSemPred : IToken); virtual; abstract;
procedure RefStringLiteral( pLiteral : IToken;
pLabel : IToken;
pAutoGenType : integer;
pLastInRule : boolean); virtual;
procedure RefToken( pAssignId : IToken;
pToken : IToken;
pLabel : IToken;
pArguments : IToken;
pInverted : boolean;
pAutoGenType : integer;
pLAstInRule : boolean); virtual;
procedure RefTokenRange( pToken1 : IToken;
pToken2 : IToken;
pLabel : IToken;
pAutoGenType : integer;
pLastInRule : boolean); virtual;
procedure RefWildCard( pToken : IToken;
pLabel : IToken;
pAutoGenType : integer); virtual; abstract;
procedure Reset; virtual;
procedure SetArgOfRuleRef( pArguments : IToken); virtual; abstract;
procedure SetCharVocabulary( pVocabulary : TByteSet);virtual;
procedure setFileOption( poption : IToken;
pValue : IToken;
pFileName : AnsiString); virtual;
procedure SetGrammarOption( pOption : IToken;
pValue : IToken); virtual;
procedure setRuleOption( pOption : IToken;
pValue : IToken); virtual; abstract;
procedure SetSubRuleOption( pOption : IToken;
pValue : IToken); virtual; abstract;
procedure SetUserExceptions( pException : AnsiString); virtual; abstract;
procedure StartLexer( pFileName : AnsiString;
pLexerName : IToken;
pSuperClass : IToken);
procedure StartParser( pFileName : AnsiString;
pParserName : IToken;
pSuperClass : IToken);
procedure StartTreeWalker( pFileName : AnsiString;
pParserName : IToken;
pSuperClass : IToken);
procedure SynPred; virtual; abstract;
procedure ZeroOrMoreSubRule; virtual; abstract;
end;
implementation
uses
System.SysUtils,
dpglib.Utils,
dpglib.Messages,
dpglib.DpgParserTokens,
dpglib.TokenSymbol,
dpglib.StringSymbol,
dpglib.RuleSymbol,
dpglib.LexerGrammar,
dpglib.ParserGrammar,
dpglib.TreeParserGrammar,
dpglib.CodeGenerator;
// ****************************************************************************
// Constructor/destructor
// ****************************************************************************
// ----------------------------------------------------------------------------
// Constructor
// ----------------------------------------------------------------------------
constructor TGrammarBehavior.Create(pTool : ITool;
pAnalyzer : ILLkAnalyzer;
pExchangeDir: AnsiString);
begin
inherited Create;
fTool := pTool;
fAnalyzer := pAnalyzer;
fLexerGrammar := nil;
fParserGrammar := nil;
fTreeWalkerGrammar:= nil;
fIsLexer := false;
fIsParser := false;
fIsTreeWalker := false;
fConstAction := nil;
fTypeAction := nil;
fLanguage := 'Delphi';
fExchangeDir := pExchangeDir;
if fExchangeDir <> '' then
if fExchangeDir[Length(fExchangeDir)] <> '\' then
fExchangeDir := fExchangeDir + '\';
end;
// ----------------------------------------------------------------------------
// Destructor
// ----------------------------------------------------------------------------
destructor TGrammarBehavior.Destroy;
begin
fTool := nil;
fAnalyzer := nil;
fLexerGrammar := nil;
fParserGrammar := nil;
fTreeWalkerGrammar:= nil;
fIsLexer := false;
fIsParser := false;
fIsTreeWalker := false;
inherited;
end;
// @@@: IGrammarBehavior implementation +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// IGrammarBehavior implementation
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ================================================================================================
// DefineGrammarUnit
// ================================================================================================
procedure TGrammarBehavior.DefineGrammarUnit(pUnit: AnsiString);
begin
fGrammar.UnitName := pUnit;
end;
// ================================================================================================
// DefineRuleName
// ================================================================================================
procedure TGrammarBehavior.DefineRuleName( pRule : IToken;
pAccess : AnsiString;
pRuleAutoGen: boolean;
pDocComment : AnsiString);
var
id: AnsiString;
ts: ITokenSymbol;
rs: IRuleSymbol;
begin
id := pRule.TokenText;
// ---------------------------------------------------------------
// Handle lexer rule definition. Lexer rule name must be TOKENREF,
// what means: must begin with capital letter.
// ---------------------------------------------------------------
if( pRule.TokenType = TT_TOKENREF) then
begin
// ------------------------------------------------------------
// construct valid name for it...
// ------------------------------------------------------------
id := TCodeGenerator.encodeLexerRuleName( id);
// ------------------------------------------------------------
// If this token not defined in TokenManager, define it. This
// happens when the rule definition is before any reference to
// this rule.
// ------------------------------------------------------------
if not fGrammar.TokenManager.TokenDefined[ pRule.TokenText] then
begin
ts := TTokenSymbol.Create( pRule.TokenText);
ts.TokenType:= fGrammar.TokenManager.NextTokenType;
fGrammar.TokenManager.Define( ts);
end;
end;
// ---------------------------------------------------------------
// Check if the rule is already defined in the grammar. If so,
// show an error message. In this case the generated code is not
// usable....
// ---------------------------------------------------------------
if fGrammar.Defined( id) then
begin
fGrammar.Symbol[id].QueryInterface(IRuleSymbol,rs);
if rs.Defined then
begin
fTool.Error( Format( MSG_E_RULEREDEF,[ id]),
fGrammar.GrammarFile,
pRule.TokenLine,
pRule.TokenColumn);
end;
end
// ---------------------------------------------------------------
// ... else the grammar isn't defined, so define it.
// ---------------------------------------------------------------
else
begin
rs := TRuleSymbol.Create( id);
fGrammar.Define( rs);
end;
rs.Defined := true;
rs.Access := pAccess;
rs.Comment := pDocComment;
end;
// ================================================================================================
// DefineToken
//
// Define a token from tokens {...}.
// Must be label and literal or just label or just a literal.
// ================================================================================================
procedure TGrammarBehavior.DefineToken( pTokenName : IToken;
pTokenLiteral : IToken);
var
i : integer;
name : AnsiString;
literal : AnsiString;
ss : IStringSymbol;
sx : IStringSymbol;
ts : ITokenSymbol;
begin
name := '';
literal := '';
if pTokenName <> nil then name := pTokenName.TokenText;
if pTokenLiteral <> nil then literal := pTokenLiteral.TokenText;
// ---------------------------------------------------------------
// The literal must be a string of printable characters surrounded
// by '"'s. See: dpglib.utils.
// ---------------------------------------------------------------
if literal <> '' then
begin
for i:=2 to Length(literal) -1 do
begin
if not IsPrint( literal[i]) then
begin
fTool.Error( Format( MSG_E_INVSTRINGLITERAL,[ literal]),
fGrammar.GrammarFile,
pTokenLiteral.TokenLine,
pTokenLiteral.TokenColumn);
exit;
end;
end;
end;
// ---------------------------------------------------------------
// OK the literal passed the test, so go...
// ---------------------------------------------------------------
if literal <> '' then
begin
ss := nil;
ts := fGrammar.TokenManager.TokenSymbol[ literal];
if ts <> nil then
ts.QueryInterface( IStringSymbol,ss);
if ss <> nil then
begin
// ---------------------------------------------------------
// This literal is known already.
// If the literal has no label already, but we can provide
// one here, then no problem, just map the label to the literal
// and don't change anything else.
// Otherwise, labels conflict: error.
// ---------------------------------------------------------
if (name = '') or (ss.Lbl <> '') then
begin
fTool.Warning( Format( MSG_W_TOKENSREDEF,[ literal]),
fGrammar.GrammarFile,
pTokenLiteral.TokenLine,
pTokenLiteral.TokenColumn);
exit;
end
// ---------------------------------------------------------
// The literal had no label, but new def does. Set it.
// ---------------------------------------------------------
else if name <> '' then
begin
ss.Lbl := name;
fGrammar.TokenManager.MapToTokenSymbol( name, ss);
end;
end;
// ------------------------------------------------------------
// if they provide a name/label and that name/label already
// exists, just hook this literal onto old token.
// ------------------------------------------------------------
if name <> '' then
begin
ts := fGrammar.TokenManager.TokenSymbol[ name];
if ts <> nil then
begin
// ------------------------------------------------------
// Watch out that the label is not more than just a token.
// If it already has a literal attached, then: conflict.
// ------------------------------------------------------
if ts.QueryInterface( IStringSymbol, sx) = S_OK then
begin
fTool.Warning( Format( MSG_W_TOKENSREDEF,[ name]),
fGrammar.GrammarFile,
pTokenName.TokenLine,
pTokenName.TokenColumn);
exit;
end;
// ------------------------------------------------------
// A simple token symbol such as DECL is defined must
// convert it to a AnsiStringLiteralSymbol with a label by
// co-opting token type and killing old TokenSymbol.
// Kill mapping and entry in vector of token manager.
// ------------------------------------------------------
// ------------------------------------------------------
// Now create AnsiString literal with label.
// ------------------------------------------------------
ss := TStringSymbol.Create( literal);
ss.TokenType := ts.TokenType;
ss.Lbl := name;
// ------------------------------------------------------
// Redefine this critter as a AnsiString literal.
// ------------------------------------------------------
fGrammar.TokenManager.Define( ss);
// ------------------------------------------------------
// Make sure the label can be used also.
// ------------------------------------------------------
fGrammar.TokenManager.MapToTokenSymbol( name, ss);
exit;
end;
end;
// ------------------------------------------------------------
// Here, literal was labeled but not by a known token symbol.
// ------------------------------------------------------------
ss := TStringSymbol.Create( literal);
ss.TokenType:= fGrammar.TokenManager.NextTokenType;
ss.Lbl := name;
fGrammar.TokenManager.Define(ss);
if name <> '' then
fGrammar.TokenManager.MapToTokenSymbol( name, ss);
end
// ---------------------------------------------------------------
// Create a token in the token manager not a literal.
// ---------------------------------------------------------------
else
begin
if fGrammar.TokenManager.TokenDefined[ name] then
begin
fTool.Warning( Format( MSG_W_TOKENSREDEF,[ name]),
fGrammar.GrammarFile,
pTokenName.TokenLine,
pTokenname.TokenColumn);
exit;
end;
ts := TTokenSymbol.Create( name);
ts.TokenType:= fGrammar.TokenManager.NextTokenType;
fGrammar.TokenManager.Define(ts);
end;
end;
// ================================================================================================
// DefineUses
// ================================================================================================
procedure TGrammarBehavior.DefineUses(pUses: AnsiString);
begin
fGrammar.UsesList.Add( pUses);
end;
// ================================================================================================
// EndOptions
//
// Called after the optional options section, to compensate for options that
// may not have been set.
// This method is bigger than it needs to be, but is much more clear if I
// delineate all the cases.
// ================================================================================================
procedure TGrammarBehavior.EndOptions;
begin
{ TODO : EndOptions not implemented... }
end;
// ================================================================================================
// refRule
// ================================================================================================
procedure TGrammarBehavior.refRule( pAssignId : IToken;
pRuleName : IToken;
pLabel : IToken;
pArguments : IToken;
pAutoGenType: integer);
begin
_refRule( pRuleName);
end;
// ============================================================================
// ============================================================================
// RefStringLiteral
// ============================================================================
procedure TGrammarBehavior.refStringLiteral( pLiteral : IToken;
pLabel : IToken;
pAutoGenType : integer;
pLastInRule : boolean);
begin
_refStringLiteral( pLiteral);
end;
// ============================================================================
// ============================================================================
// RefToken
// ============================================================================
procedure TGrammarBehavior.refToken( pAssignId : IToken;
pToken : IToken;
pLabel : IToken;
pArguments : IToken;
pInverted : boolean;
pAutoGenType : integer;
pLAstInRule : boolean);
begin
_refToken( pToken);
end;
// ============================================================================
// ============================================================================
// RefTokenRange
// ============================================================================
procedure TGrammarBehavior.refTokenRange( pToken1 : IToken;
pToken2 : IToken;
pLabel : IToken;
pAutoGenType : integer;
pLastInRule : boolean);
begin
// ---------------------------------------------------------------
// Ensure that the DefineGrammar methods are called;
// otherwise a range addes more token refs to the alternative by
// calling MakeGrammar.refToken etc...
// ---------------------------------------------------------------
if pToken1.TokenText[1] = '"' then
_refStringLiteral( pToken1)
else
_RefToken( pToken1);
if pToken2.TokenText[1] = '"' then
_RefStringLiteral( pToken2)
else
_RefToken( pToken2);
end;
// ============================================================================
// ============================================================================
// SetCharVocabulary
//
// Set the character vocabulary for a lexer.
// ============================================================================
procedure TGrammarBehavior.SetCharVocabulary(pVocabulary: TByteSet);
begin
if fIsLexer then
fLexerGrammar.CharVocabulary := pVocabulary;
end;
// ============================================================================
// ============================================================================
// SetFileOption
// ============================================================================
procedure TGrammarBehavior.SetFileOption( pOption : IToken;
pValue : IToken;
pFileName: AnsiString);
begin
// ---------------------------------------------------------------
// Option: language
// ---------------------------------------------------------------
if pOption.TokenText = 'language' then
if pValue.TokenType = TT_STRINGLIT then
fLanguage := Copy(pValue.TokenText,2,Length(pValue.TokenText)-2)
else if pValue.TokenType in [TT_TOKENREF,TT_RULEREF] then
fLanguage := pValue.TokenText
else
fTool.Error( 'option "language" must be a AnsiString or identifier',
fGrammar.GrammarFile,
pValue.TokenLine,
pValue.TokenColumn)
// ---------------------------------------------------------------
// Other option is error
// ---------------------------------------------------------------
else
fTool.Error( 'Invalid file-level option: "' + poption.TokenText + '"',
fGrammar.GrammarFile,
pValue.TokenLine,
pValue.TokenColumn)
end;
// ----------------------------------------------------------------------------
// SetGrammarOption
// ----------------------------------------------------------------------------
procedure TGrammarBehavior.SetGrammarOption( pOption : IToken;
pValue : IToken);
begin
// ---------------------------------------------------------------
// Option: exportVocab
// ---------------------------------------------------------------
if pOption.TokenText = 'exportVocab' then
if pValue.TokenType in [TT_TOKENREF,TT_RULEREF] then
// fGrammar.ExportVocab := fExchangeDir + pValue.TokenText
fGrammar.ExportVocab := pValue.TokenText
else
fTool.Error( 'option "exportVocab" must be an identifier',
fGrammar.GrammarFile,
pValue.TokenLine,
pValue.TokenColumn)
// ---------------------------------------------------------------
// Option: importVocab
// ---------------------------------------------------------------
else if pOption.TokenText = 'importVocab' then
if pValue.TokenType in [TT_TOKENREF,TT_RULEREF] then
begin
pValue.TokenText := fExchangeDir + pValue.TokenText;
fGrammar.ImportVocab := pValue
end
else
fTool.Error( 'option "importVocab" must be an identifier',
fGrammar.GrammarFile,
pValue.TokenLine,
pValue.TokenColumn)
// ---------------------------------------------------------------
// Other options sent to the grammar
// ---------------------------------------------------------------
else
fGrammar.SetOption( pOption, pValue);
end;
// ================================================================================================
// Start Lexer
// ================================================================================================
procedure TGrammarBehavior.StartLexer( pFileName : AnsiString;
pLexerName : IToken;
pSuperClass : IToken);
begin
// ---------------------------------------------------------------
// Create lexer, and initialize it
// ---------------------------------------------------------------
if fGrammar = nil then
begin
fLexerGrammar := TLexerGrammar.Create(pLexerName,fTool,pSuperClass);
fGrammar := fLexerGrammar;
fGrammar.LLkAnalyzer := fAnalyzer;
fGrammar.GrammarFile := pFileName;
fAnalyzer.Grammar := fGrammar;
fIsLexer := true;
// ------------------------------------------------------------
// Append uses list...
// ------------------------------------------------------------
fGrammar.UsesList.AddStrings( fUsesList);
fGrammar.ConstAction := fConstAction;
fGrammar.TypeAction := fTypeAction;
end
else
fTool.Panic('A grammar already started');
end;
// ================================================================================================
// Start Parser
// ================================================================================================
procedure TGrammarBehavior.StartParser( pFileName : AnsiString;
pParserName : IToken;
pSuperClass : IToken);
begin
// ---------------------------------------------------------------
// Create parser, and initialize it
// ---------------------------------------------------------------
if fGrammar = nil then
begin
fParserGrammar := TParserGrammar.Create(pParserName,fTool,pSuperClass);
fGrammar := fParserGrammar;
fGrammar.LLkAnalyzer := fAnalyzer;
fGrammar.GrammarFile := pFileName;
fAnalyzer.Grammar := fGrammar;
fIsParser := true;
// ------------------------------------------------------------
// Append uses list...
// ------------------------------------------------------------
fGrammar.UsesList.AddStrings( fUsesList);
fGrammar.ConstAction := fConstAction;
fGrammar.TypeAction := fTypeAction;
end
else
fTool.Panic('A grammar already started');
end;
// ================================================================================================
// Start TreeWalker
// ================================================================================================
procedure TGrammarBehavior.StartTreeWalker( pFileName : AnsiString;
pParserName : IToken;
pSuperClass : IToken);
begin
// ---------------------------------------------------------------
// Create parser, and initialize it
// ---------------------------------------------------------------
if fGrammar = nil then
begin
fTreeWalkerGrammar := TTreeParserGrammar.Create( pParserName,fTool,pSuperClass);
fGrammar := fTreeWalkerGrammar;
fGrammar.GrammarFile := pFileName;
fGrammar.LLkAnalyzer := fAnalyzer;
fAnalyzer.Grammar := fGrammar;
fIsParser := true;
// ------------------------------------------------------------
// Append uses list...
// ------------------------------------------------------------
fGrammar.UsesList.AddStrings( fUsesList);
fGrammar.ConstAction := fConstAction;
fGrammar.TypeAction := fTypeAction;
end
else
fTool.Panic('A grammar already started');
end;
// ============================================================================
// ============================================================================
// RefMemberDecl
// ============================================================================
procedure TGrammarBehavior.RefMemberDecl(pDecl: IToken);
begin
if pDecl <> nil then
fGrammar.MemberDecl := pDecl.TokenText;
end;
// ============================================================================
// ============================================================================
// RefMemberDef
// ============================================================================
procedure TGrammarBehavior.RefMemberDef(pDef: IToken);
begin
if pDef <> nil then
fGrammar.MemberDef := pDef.TokenText;
end;
// ============================================================================
// ============================================================================
// Grammar
// ============================================================================
function TGrammarBehavior.Grammar: IGrammar;
begin
result := fGrammar;
end;
// ============================================================================
// ============================================================================
// AbortGrammar
// ============================================================================
procedure TGrammarBehavior.AbortGrammar;
begin
Reset;
end;
// ============================================================================
// ============================================================================
// Reset
// ============================================================================
procedure TGrammarBehavior.Reset;
begin
fGrammar := nil;
fLexerGrammar := nil;
fParserGrammar := nil;
fTreeWalkerGrammar:= nil;
end;
// ****************************************************************************
// Internals
// ****************************************************************************
// ============================================================================
// ============================================================================
// _RefStringLiteral
//
// AnsiStringLiterals are treated like tokens except by the lexer.
// ============================================================================
procedure TGrammarBehavior._RefStringLiteral( pLiteral: IToken);
var
ss : IStringSymbol;
str: AnsiString;
begin
if not fIsLexer then
begin
str := pLiteral.TokenText;
if fGrammar.TokenManager.TokenSymbol[str] = nil then
begin
// fTool.Warning( 'String literal "' + str + '" not defined.',
// fGrammar.GrammarFile,
// pLiteral.TokenLine,
// pLiteral.TokenColumn);
// ss := TStringSymbol.Create( str);
// ss.TokenType:= fGrammar.TokenManager.NextTokenType;
// fGrammar.TokenManager.Define( ss);
end;
end;
end;
// ============================================================================
// ============================================================================
// _RefToken
// ============================================================================
procedure TGrammarBehavior._RefToken( pToken: IToken);
var
id: AnsiString;
ts: ITokenSymbol;
begin
id := pToken.TokenText;
if not fGrammar.TokenManager.TokenDefined[ id] then
begin
// ------------------------------------------------------------
// Defining new TOKENREF is only allowed in lexer..
// ------------------------------------------------------------
if fIsLexer then
begin
ts := TTokenSymbol.Create( id);
ts.TokenType:= fGrammar.TokenManager.NextTokenType;
fGrammar.TokenManager.Define( ts);
end;
end;
end;
// ============================================================================
// ============================================================================
// _refRule
// ============================================================================
procedure TGrammarBehavior._RefRule( pRuleName: IToken);
var
id: AnsiString;
begin
id := pRuleName.TokenText;
if pRuleName.TokenType = TT_TOKENREF then
id := TCodeGenerator.encodeLexerRuleName( id);
if not fGrammar.Defined( id) then
fGrammar.Define( TRuleSymbol.Create( id));
end;
// ============================================================================
// ============================================================================
// RefConstAction
// ============================================================================
procedure TGrammarBehavior.RefConstAction(pConstAction: IToken);
begin
fConstAction := pConstAction;
end;
// ============================================================================
// ============================================================================
// RefTypeAction
// ============================================================================
procedure TGrammarBehavior.RefTypeAction(pTypeAction: IToken);
begin
fTypeAction := pTypeAction;
end;
end.