Initial check in lib
This commit is contained in:
@@ -0,0 +1,950 @@
|
||||
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.
|
||||
Reference in New Issue
Block a user