Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
5.3 KiB

  1. // Copyright (c) 1999 Microsoft Corporation. All rights reserved.
  2. //
  3. // Declaration of Parser.
  4. //
  5. #pragma once
  6. #include "englex.h"
  7. #include "englookup.h"
  8. #include "activescript.h"
  9. #include "engcontrol.h"
  10. // Parser for AudioVBScript. Reads tokens from Lexer and produces program structures ready for execution.
  11. //////////////////////////////////////////////////////////////////////
  12. // helper structures
  13. // saves the identifier of a dereference like x.y where y would be the name. used to map char * into single instances in strings during parsing.
  14. class Name_Parse
  15. {
  16. public:
  17. Name_Parse(Strings::index _istrIdentifier = 0) : istrIdentifier(_istrIdentifier) {}
  18. Strings::index istrIdentifier;
  19. };
  20. typedef Slots<Name_Parse> Names_Parse;
  21. // Holds information about an identifier (eg "x") or identifiers (eg "x.y") until the context it will be
  22. // used in (variable reference or function call) becomes known.
  23. // Returned by ParseNameReference. Used later with VariableReferenceFromNameReference or CallFromNameReference.
  24. struct NameReference
  25. {
  26. NameReference() : fSingleItem(true), ivarrefMultiple(0) {}
  27. bool fSingleItem;
  28. SmartRef::AString strSingle; // used if fSingleItem is true: this saves the name until we know whether it's the name or a variable or a function
  29. VariableReferences::index ivarrefMultiple; // used if fSingleItem is false: it must reference a variable
  30. };
  31. //////////////////////////////////////////////////////////////////////
  32. // error codes
  33. enum ParseErr
  34. {
  35. PARSEERR_LexerError = 0,
  36. PARSEERR_ExpectedSubOrDim,
  37. PARSEERR_ExpectedIdentifier,
  38. PARSEERR_ExpectedLineBreak,
  39. PARSEERR_ExpectedEndSub,
  40. PARSEERR_ExpectedSub,
  41. PARSEERR_ExpectedStatement,
  42. PARSEERR_ExpectedLparen,
  43. PARSEERR_ExpectedEq,
  44. PARSEERR_DimAfterSub,
  45. PARSEERR_InvalidExprLineBreak,
  46. PARSEERR_InvalidExprThen,
  47. PARSEERR_InvalidExprRparen,
  48. PARSEERR_StringInExprBlock,
  49. PARSEERR_ExpectedExprValue,
  50. PARSEERR_DuplicateVariable,
  51. PARSEERR_DuplicateRoutine,
  52. PARSEERR_ExpectedRparen,
  53. PARSEERR_UnexpectedRparen,
  54. PARSEERR_ExpectedThen,
  55. PARSEERR_ExpectedEndIf,
  56. PARSEERR_ExpectedIf,
  57. PARSEERR_IntendedElseIf,
  58. PARSEERR_AssignedToBuiltInConstant,
  59. PARSEERR_ParensUsedCallingSub,
  60. PARSEERR_ExpectedVariableButRoutineFound,
  61. PARSEERR_Max
  62. };
  63. //////////////////////////////////////////////////////////////////////
  64. // Parser class
  65. class Parser
  66. {
  67. public:
  68. Parser(Lexer &lexer, Script &script, IActiveScriptSite *pActiveScriptSite, IDispatch *pGlobalDispatch);
  69. ~Parser();
  70. HRESULT hr() { return m_hr; }
  71. private:
  72. // Parsing functions. Each reads a certain kind of structure. m_hr and m_pexcepinfo are set on failure.
  73. void ParseScript();
  74. void ParseSub();
  75. void ParseDim();
  76. Statements::index ParseStatements(Routines::index irtnContext, Lookup &lkuLocals);
  77. void ParseAssignmentOrCall(Routines::index irtnContext, Lookup &lkuLocals, bool fSet, bool fCall);
  78. VariableReferences::index ParseDottedVariableReference(Routines::index irtnContext, Lookup &lkuLocals);
  79. Assignments::index ParseAssignment(Routines::index irtnContext, Lookup &lkuLocals, bool fSet, VariableReferences::index ivarrefLHS);
  80. void ParseIf(Routines::index irtnContext, Lookup &lkuLocals);
  81. ExprBlocks::index ParseExpression(Routines::index irtnContext, Lookup &lkuLocals, ExprBlocks *peblocks, bool fAllowRparenAtEnd, bool fDetectSpecialErrorForSubCallWithParen);
  82. ExprBlocks::index ParseParameters(Routines::index irtnContext, Lookup &lkuLocals, bool fParenthesized);
  83. void ParseNameReference(Routines::index irtnContext, Lookup &lkuLocals, NameReference &nref);
  84. // Parsing helpers.
  85. // Advance the lexer one token. If an error token is encountered, the error is reported and true is returned.
  86. bool Advance() { if (!++m_lexer && m_lexer.error_num()) { Error(PARSEERR_LexerError); return true; } return false; }
  87. // Advances if the current token is t. If an error token is next, it is reported and true is returned.
  88. bool Skip(Token t) { if (m_lexer == t) { return Advance(); } return false; }
  89. // Same as Skip, but if t isn't next then the error iErr is reported and true is returned.
  90. bool Expect(Token t, ParseErr iErr) { if (m_lexer == t) { return Advance(); } Error(iErr); return true; }
  91. // Advance. If the next token isn't t then report iErr and return true.
  92. bool ExpectNext(Token t, ParseErr iErr) { if (Advance()) return true; if (m_lexer == t) return false; Error(iErr); return true; }
  93. // Add a variable reference using the info from a NameReference.
  94. VariableReferences::index VariableReferenceFromNameReference(Routines::index irtnContext, Lookup &lkuLocals, const NameReference &nref);
  95. // Add a call using the info from a NameReference. Also parses the parameters.
  96. Calls::index CallFromNameReference(Routines::index irtnContext, Lookup &lkuLocals, const NameReference &nref, bool fParametersParenthesized);
  97. // Shared implementation for VariableReferenceFromNameReference (pszName is set) and ParseDottedVariableReference (pszName is NULL).
  98. VariableReferences::index VariableReferenceInternal(Routines::index irtnContext, Lookup &lkuLocals, const char *pszName);
  99. void Error(ParseErr iErr); // call to report a syntax error
  100. Lexer &m_lexer;
  101. Script &m_script;
  102. HRESULT m_hr;
  103. IActiveScriptSite *m_pActiveScriptSite;
  104. IDispatch *m_pGlobalDispatch;
  105. Lookup *m_plkuRoutines;
  106. Lookup *m_plkuGlobals;
  107. Lookup *m_plkuVarRefs;
  108. Lookup *m_plkuNames;
  109. Names_Parse m_names;
  110. SmartRef::Stack<ExprBlock> m_stack; // working stack for expression evaluation
  111. };