📄 sg_pascal.cpp
字号:
//
// Pascal Parser Grammar for Spirit (http://spirit.sourceforge.net/)
//
//
// Adapted from,
// Pascal User Manual And Report (Second Edition-1978)
// Kathleen Jensen - Niklaus Wirth
//
// Written by: Hakki Dogusan dogusanh@tr.net
// Adapted by Joel de Guzman djowel@gmx.co.uk
//
//#define SPIRIT_DEBUG ///$$$ DEFINE THIS WHEN DEBUGGING $$$///
#include "boost/spirit/spirit.hpp"
#include <iostream>
#include <fstream>
#include <vector>
/////////////////////////////////////////////////////////////////////////////////////////
using namespace spirit;
using namespace std;
static populate_vector(istream_iterator<char> begin, istream_iterator<char> end,
vector<char> & vec)
{
while (begin != end)
{
vec.push_back(*begin);
++begin;
}
};
/////////////////////////////////////////////////////////////////////////////////////////
static void
parse(rule<> const& r, char const* filename)
{
cout << "/////////////////////////////////////////////////////////\n\n";
ifstream in(filename);
if (!in)
{
cout << "Could not open file: " << filename << endl;
return;
}
// Turn of white space skipping on the stream
in.unsetf(ios::skipws);
// Here's our nested pascal comment rule
rule<char const*> comment
= '{' >> (*(anychar - '}')) >> '}' // pascal comment 1
| "(*" >> (*(anychar - "*)")) >> "*)" // pascal comment 2
;
vector<char> vec;
populate_vector(istream_iterator<char>(in), istream_iterator<char>(), vec);
vector<char> const& cvec = vec;
parse_info<char const*>
result = parse(&*cvec.begin(), &*cvec.end(), r, space | comment);
if (result.full)
{
cout << "\t\t" << filename << " Parses OK\n\n\n";
}
else
{
cout << "===========================================\n";
cout << filename << " Fails Parsing\n";
cout << "===========================================\n";
for (int i = 0; i < 50; i++)
{
if (result.stop == &*cvec.end())
break;
cout << *result.stop++;
}
cout << endl;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
int
main(int argc, char* argv[])
{
cout << "/////////////////////////////////////////////////////////\n\n";
cout << "\t\tPascal Grammar For Spirit...\n\n";
cout << "/////////////////////////////////////////////////////////\n\n";
//----------------------------------------------------------------------------
// Start grammar definition
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// KEYWORDS
//----------------------------------------------------------------------------
symbols<> keywords;
keywords =
"in", "div", "mod", "and", "or", "not", "nil", "goto", "if",
"then", "else", "case", "while", "repeat", "until", "for",
"do", "to", "downto", "with", "program", "label", "const",
"type", "char", "boolean", "integer", "real", "packed",
"array", "of", "record", "end", "set", "file", "var",
"procedure", "function", "begin";
//----------------------------------------------------------------------------
// OPERATORS
//----------------------------------------------------------------------------
chlit<> PLUS('+');
chlit<> MINUS('-');
chlit<> STAR('*');
chlit<> SLASH('/');
strlit<> ASSIGN(":=");
chlit<> COMMA(',');
chlit<> SEMI(';');
chlit<> COLON(':');
chlit<> EQUAL('=');
strlit<> NOT_EQUAL("<>");
chlit<> LT('<');
strlit<> LE("<=");
strlit<> GE(">=");
chlit<> GT('>');
chlit<> LPAREN('(');
chlit<> RPAREN(')');
chlit<> LBRACK('[');
chlit<> RBRACK(']');
chlit<> POINTER('^');
chlit<> DOT('.');
strlit<> DOTDOT("..");
//----------------------------------------------------------------------------
// TOKENS
//----------------------------------------------------------------------------
rule<> IN = nocase["in"];
rule<> DIV = nocase["div"];
rule<> MOD = nocase["mod"];
rule<> AND = nocase["and"];
rule<> OR = nocase["or"];
rule<> NOT = nocase["not"];
rule<> NIL = nocase["nil"];
rule<> GOTO = nocase["goto"];
rule<> IF = nocase["if"];
rule<> THEN = nocase["then"];
rule<> ELSE = nocase["else"];
rule<> CASE = nocase["case"];
rule<> WHILE = nocase["while"];
rule<> REPEAT = nocase["repeat"];
rule<> UNTIL = nocase["until"];
rule<> FOR = nocase["for"];
rule<> DO = nocase["do"];
rule<> TO = nocase["to"];
rule<> DOWNTO = nocase["downto"];
rule<> WITH = nocase["with"];
rule<> PROGRAM = nocase["program"];
rule<> LABEL = nocase["label"];
rule<> CONST = nocase["const"];
rule<> TYPE = nocase["type"];
rule<> CHAR = nocase["char"];
rule<> BOOLEAN = nocase["boolean"];
rule<> INTEGER = nocase["integer"];
rule<> REAL = nocase["real"];
rule<> PACKED = nocase["packed"];
rule<> ARRAY = nocase["array"];
rule<> OF = nocase["of"];
rule<> RECORD = nocase["record"];
rule<> END = nocase["end"];
rule<> SET = nocase["set"];
rule<> FILE = nocase["file"];
rule<> VAR = nocase["var"];
rule<> PROCEDURE = nocase["procedure"];
rule<> FUNCTION = nocase["function"];
rule<> BEGIN = nocase["begin"];
rule<> IDENT
= nocase[
lexeme[
(alpha >> *(alnum | '_'))
- (keywords >> anychar - (alnum | '_'))
]
];
rule<> STRING_LITERAL = lexeme[ chlit<>('\'') >>
+( strlit<>("\'\'") | anychar-chlit<>('\'') ) >>
chlit<>('\'') ];
//----------------------------------------------------------------------------
// RULES
//----------------------------------------------------------------------------
rule<> program;
rule<> programHeading;
rule<> fileIdentifier;
rule<> identifier;
rule<> block;
rule<> labelDeclarationPart;
rule<> label;
rule<> constantDefinitionPart;
rule<> constantDefinition;
rule<> constant;
rule<> unsignedNumber;
rule<> unsignedInteger;
rule<> unsignedReal;
rule<> sign;
rule<> constantIdentifier;
rule<> string;
rule<> typeDefinitionPart;
rule<> typeDefinition;
rule<> type;
rule<> simpleType;
rule<> scalarType;
rule<> subrangeType;
rule<> typeIdentifier;
rule<> structuredType;
rule<> unpackedStructuredType;
rule<> arrayType;
rule<> indexType;
rule<> componentType;
rule<> recordType;
rule<> fieldList;
rule<> fixedPart;
rule<> recordSection;
rule<> variantPart;
rule<> tagField;
rule<> variant;
rule<> caseLabelList;
rule<> caseLabel;
rule<> setType;
rule<> baseType;
rule<> fileType;
rule<> pointerType;
rule<> variableDeclarationPart;
rule<> variableDeclaration;
rule<> procedureAndFunctionDeclarationPart;
rule<> procedureOrFunctionDeclaration;
rule<> procedureDeclaration;
rule<> procedureHeading;
rule<> parameterList;
rule<> formalParameterSection;
rule<> parameterGroup;
rule<> functionDeclaration;
rule<> functionHeading;
rule<> resultType;
rule<> statementPart;
rule<> statement;
rule<> unlabelledStatement;
rule<> simpleStatement;
rule<> assignmentStatement;
rule<> variable;
rule<> entireVariable;
rule<> variableIdentifier;
rule<> componentVariable;
rule<> indexedVariable;
rule<> arrayVariable;
rule<> fieldDesignator;
rule<> recordVariable;
rule<> fieldIdentifier;
rule<> fileBuffer;
rule<> fileVariable;
rule<> referencedVariable;
rule<> pointerVariable;
rule<> expression;
rule<> relationalOperator;
rule<> simpleExpression;
rule<> addingOperator;
rule<> term;
rule<> multiplyingOperator;
rule<> factor;
rule<> unsignedConstant;
rule<> functionDesignator;
rule<> functionIdentifier;
rule<> set;
rule<> elementList;
rule<> element;
rule<> procedureStatement;
rule<> procedureIdentifier;
rule<> actualParameter;
rule<> gotoStatement;
rule<> emptyStatement;
rule<> empty;
rule<> structuredStatement;
rule<> compoundStatement;
rule<> conditionalStatement;
rule<> ifStatement;
rule<> caseStatement;
rule<> caseListElement;
rule<> repetetiveStatement;
rule<> whileStatement;
rule<> repeatStatement;
rule<> forStatement;
rule<> forList;
rule<> controlVariable;
rule<> initialValue;
rule<> finalValue;
rule<> withStatement;
rule<> recordVariableList;
#ifdef SPIRIT_DEBUG
SPIRIT_DEBUG_RULE(program);
SPIRIT_DEBUG_RULE(programHeading);
SPIRIT_DEBUG_RULE(fileIdentifier);
SPIRIT_DEBUG_RULE(identifier);
SPIRIT_DEBUG_RULE(block);
SPIRIT_DEBUG_RULE(labelDeclarationPart);
SPIRIT_DEBUG_RULE(label);
SPIRIT_DEBUG_RULE(constantDefinitionPart);
SPIRIT_DEBUG_RULE(constantDefinition);
SPIRIT_DEBUG_RULE(constant);
SPIRIT_DEBUG_RULE(unsignedNumber);
SPIRIT_DEBUG_RULE(unsignedInteger);
SPIRIT_DEBUG_RULE(unsignedReal);
SPIRIT_DEBUG_RULE(sign);
SPIRIT_DEBUG_RULE(constantIdentifier);
SPIRIT_DEBUG_RULE(string);
SPIRIT_DEBUG_RULE(typeDefinitionPart);
SPIRIT_DEBUG_RULE(typeDefinition);
SPIRIT_DEBUG_RULE(type);
SPIRIT_DEBUG_RULE(simpleType);
SPIRIT_DEBUG_RULE(scalarType);
SPIRIT_DEBUG_RULE(subrangeType);
SPIRIT_DEBUG_RULE(typeIdentifier);
SPIRIT_DEBUG_RULE(structuredType);
SPIRIT_DEBUG_RULE(unpackedStructuredType);
SPIRIT_DEBUG_RULE(arrayType);
SPIRIT_DEBUG_RULE(indexType);
SPIRIT_DEBUG_RULE(componentType);
SPIRIT_DEBUG_RULE(recordType);
SPIRIT_DEBUG_RULE(fieldList);
SPIRIT_DEBUG_RULE(fixedPart);
SPIRIT_DEBUG_RULE(recordSection);
SPIRIT_DEBUG_RULE(variantPart);
SPIRIT_DEBUG_RULE(tagField);
SPIRIT_DEBUG_RULE(variant);
SPIRIT_DEBUG_RULE(caseLabelList);
SPIRIT_DEBUG_RULE(caseLabel);
SPIRIT_DEBUG_RULE(setType);
SPIRIT_DEBUG_RULE(baseType);
SPIRIT_DEBUG_RULE(fileType);
SPIRIT_DEBUG_RULE(pointerType);
SPIRIT_DEBUG_RULE(variableDeclarationPart);
SPIRIT_DEBUG_RULE(variableDeclaration);
SPIRIT_DEBUG_RULE(procedureAndFunctionDeclarationPart);
SPIRIT_DEBUG_RULE(procedureOrFunctionDeclaration);
SPIRIT_DEBUG_RULE(procedureDeclaration);
SPIRIT_DEBUG_RULE(procedureHeading);
SPIRIT_DEBUG_RULE(parameterList);
SPIRIT_DEBUG_RULE(formalParameterSection);
SPIRIT_DEBUG_RULE(parameterGroup);
SPIRIT_DEBUG_RULE(functionDeclaration);
SPIRIT_DEBUG_RULE(functionHeading);
SPIRIT_DEBUG_RULE(resultType);
SPIRIT_DEBUG_RULE(statementPart);
SPIRIT_DEBUG_RULE(statement);
SPIRIT_DEBUG_RULE(unlabelledStatement);
SPIRIT_DEBUG_RULE(simpleStatement);
SPIRIT_DEBUG_RULE(assignmentStatement);
SPIRIT_DEBUG_RULE(variable);
SPIRIT_DEBUG_RULE(entireVariable);
SPIRIT_DEBUG_RULE(variableIdentifier);
SPIRIT_DEBUG_RULE(componentVariable);
SPIRIT_DEBUG_RULE(indexedVariable);
SPIRIT_DEBUG_RULE(arrayVariable);
SPIRIT_DEBUG_RULE(fieldDesignator);
SPIRIT_DEBUG_RULE(recordVariable);
SPIRIT_DEBUG_RULE(fieldIdentifier);
SPIRIT_DEBUG_RULE(fileBuffer);
SPIRIT_DEBUG_RULE(fileVariable);
SPIRIT_DEBUG_RULE(referencedVariable);
SPIRIT_DEBUG_RULE(pointerVariable);
SPIRIT_DEBUG_RULE(expression);
SPIRIT_DEBUG_RULE(relationalOperator);
SPIRIT_DEBUG_RULE(simpleExpression);
SPIRIT_DEBUG_RULE(addingOperator);
SPIRIT_DEBUG_RULE(term);
SPIRIT_DEBUG_RULE(multiplyingOperator);
SPIRIT_DEBUG_RULE(factor);
SPIRIT_DEBUG_RULE(unsignedConstant);
SPIRIT_DEBUG_RULE(functionDesignator);
SPIRIT_DEBUG_RULE(functionIdentifier);
SPIRIT_DEBUG_RULE(set);
SPIRIT_DEBUG_RULE(elementList);
SPIRIT_DEBUG_RULE(element);
SPIRIT_DEBUG_RULE(procedureStatement);
SPIRIT_DEBUG_RULE(procedureIdentifier);
SPIRIT_DEBUG_RULE(actualParameter);
SPIRIT_DEBUG_RULE(gotoStatement);
SPIRIT_DEBUG_RULE(emptyStatement);
SPIRIT_DEBUG_RULE(empty);
SPIRIT_DEBUG_RULE(structuredStatement);
SPIRIT_DEBUG_RULE(compoundStatement);
SPIRIT_DEBUG_RULE(conditionalStatement);
SPIRIT_DEBUG_RULE(ifStatement);
SPIRIT_DEBUG_RULE(caseStatement);
SPIRIT_DEBUG_RULE(caseListElement);
SPIRIT_DEBUG_RULE(repetetiveStatement);
SPIRIT_DEBUG_RULE(whileStatement);
SPIRIT_DEBUG_RULE(repeatStatement);
SPIRIT_DEBUG_RULE(forStatement);
SPIRIT_DEBUG_RULE(forList);
SPIRIT_DEBUG_RULE(controlVariable);
SPIRIT_DEBUG_RULE(initialValue);
SPIRIT_DEBUG_RULE(finalValue);
SPIRIT_DEBUG_RULE(withStatement);
SPIRIT_DEBUG_RULE(recordVariableList);
#endif
program
= programHeading >>
block >>
DOT
;
programHeading
= PROGRAM >> identifier >>
LPAREN >> fileIdentifier >> *( COMMA >> fileIdentifier ) >> RPAREN >>
SEMI
;
fileIdentifier
= identifier
;
identifier
= IDENT
;
block
= *( labelDeclarationPart
| constantDefinitionPart
| typeDefinitionPart
| variableDeclarationPart
| procedureAndFunctionDeclarationPart
) >>
statementPart
;
labelDeclarationPart
= LABEL >> label >> *( COMMA >> label ) >> SEMI
;
label
= unsignedInteger
;
constantDefinitionPart
= CONST >> constantDefinition >> *( SEMI >> constantDefinition ) >> SEMI
;
constantDefinition
= identifier >> EQUAL >> constant
;
constant
= unsignedNumber
| sign >> unsignedNumber
| constantIdentifier
| sign >> constantIdentifier
| string
;
unsignedNumber
= lexeme[uint_p
>> !('.' >> uint_p)
>> !(nocase['e'] >> (ch_p('+') | '-') >> uint_p)]
;
unsignedInteger
= uint_p
;
unsignedReal
= ureal_p
;
sign
= PLUS | MINUS
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -