Skip to content

Commit

Permalink
ABS grammar recovery (agile)
Browse files Browse the repository at this point in the history
  • Loading branch information
grammarware committed May 30, 2012
1 parent 43e7089 commit a889685
Show file tree
Hide file tree
Showing 6 changed files with 368 additions and 0 deletions.
191 changes: 191 additions & 0 deletions topics/export/rascal/bgf2rsc-unsafe.xslt
@@ -0,0 +1,191 @@
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:bgf="http://planet-sl.org/bgf" xmlns:xhtml="http://www.w3.org/1999/xhtml" version="1.0">
<xsl:output method="text" encoding="UTF-8" omit-xml-declaration="yes"/>
<xsl:param name="grammarname"/>
<xsl:param name="imports" default="''"/>
<xsl:template match="/bgf:grammar">
<xsl:text>@contributor{bgf2src automated exporter - SLPS}
module </xsl:text>
<xsl:value-of select="$grammarname"/>
<xsl:text>

</xsl:text>
<xsl:if test="$imports">
<xsl:text>import </xsl:text>
<xsl:value-of select="$imports"/>
<xsl:text>;

</xsl:text>
</xsl:if>
<xsl:apply-templates select="./bgf:*"/>
</xsl:template>
<xsl:template match="bgf:production">
<xsl:text>syntax </xsl:text>
<xsl:apply-templates select="./nonterminal"/>
<xsl:text>
= </xsl:text>
<xsl:if test="./label">
<xsl:value-of select="./label"/>
<xsl:text>: </xsl:text>
</xsl:if>
<xsl:choose>
<xsl:when test="./bgf:expression/choice">
<xsl:for-each select="./bgf:expression/choice/bgf:expression">
<xsl:if test="position()!= 1">
<xsl:text>
| </xsl:text>
</xsl:if>
<xsl:call-template name="no-parenthesis">
<xsl:with-param name="expr" select="."/>
</xsl:call-template>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>
</xsl:text>
<xsl:call-template name="no-parenthesis">
<xsl:with-param name="expr" select="./bgf:expression"/>
</xsl:call-template>
<xsl:text>
</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:text> ;
</xsl:text>
</xsl:template>
<xsl:template match="bgf:expression">
<xsl:apply-templates select="./*"/>
</xsl:template>
<xsl:template match="marked">
<!-- do not exist in Rascal -->
<xsl:text>(</xsl:text>
<xsl:apply-templates select="./*"/>
<xsl:text>)</xsl:text>
</xsl:template>
<xsl:template match="plus">
<xsl:apply-templates select="./*"/>
<xsl:text>+</xsl:text>
</xsl:template>
<xsl:template match="star">
<xsl:apply-templates select="./*"/>
<xsl:text>*</xsl:text>
</xsl:template>
<xsl:template match="optional">
<!-- (N ("," N)*)? is treated as {N ","}* -->
<xsl:choose>
<xsl:when test="local-name(./bgf:expression/*[1]) = 'sequence' and ./bgf:expression/sequence/bgf:expression[1]/*[1] = ./bgf:expression/sequence/bgf:expression[2]/star/bgf:expression/sequence/bgf:expression[2]/*[1]">
<xsl:text>{</xsl:text>
<xsl:apply-templates select="./bgf:expression/sequence/bgf:expression[1]"/>
<xsl:text> </xsl:text>
<xsl:apply-templates select="./bgf:expression/sequence/bgf:expression[2]/star/bgf:expression/sequence/bgf:expression[1]"/>
<xsl:text>}*</xsl:text>
</xsl:when>
<!-- TODO: N ("," N)*) is NOT treated as {N ","}+ -->
<xsl:otherwise>
<xsl:apply-templates select="./*"/>
<xsl:text>?</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="terminal">
<xsl:text>"</xsl:text>
<xsl:call-template name="escape">
<xsl:with-param name="t" select="."/>
</xsl:call-template>
<xsl:text>"</xsl:text>
</xsl:template>
<xsl:template match="value">
<xsl:choose>
<xsl:when test=". = 'string'">
<xsl:text>String</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>Integer</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="epsilon">
<xsl:text>()</xsl:text>
</xsl:template>
<xsl:template match="empty">
<xsl:text>()</xsl:text>
</xsl:template>
<xsl:template match="any">
<xsl:text>ANY</xsl:text>
</xsl:template>
<xsl:template match="nonterminal">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="selectable">
<xsl:choose>
<xsl:when test="local-name(bgf:expression/*) = 'star' or local-name(bgf:expression/*) = 'optional' or local-name(bgf:expression/*) = 'plus'">
<!-- <xsl:text>&lt;</xsl:text> -->
<xsl:apply-templates select="bgf:expression"/>
<xsl:text> </xsl:text>
<xsl:value-of select="selector"/>
<!-- <xsl:text>&gt;</xsl:text>-->
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="bgf:expression"/>
<xsl:text> </xsl:text>
<xsl:value-of select="selector"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="sequence">
<xsl:text>(</xsl:text>
<xsl:apply-templates select="./bgf:expression[1]/*"/>
<xsl:for-each select="./bgf:expression[position()&gt;1]">
<xsl:text> </xsl:text>
<xsl:apply-templates select="./*"/>
</xsl:for-each>
<xsl:text>)</xsl:text>
</xsl:template>
<!-- inner choices - BNF bar -->
<xsl:template match="choice">
<xsl:text>(</xsl:text>
<xsl:apply-templates select="./bgf:expression[1]/*"/>
<xsl:for-each select="./bgf:expression[position()&gt;1]">
<xsl:text> | </xsl:text>
<xsl:apply-templates select="./*"/>
</xsl:for-each>
<xsl:text>)</xsl:text>
</xsl:template>
<xsl:template name="no-parenthesis">
<xsl:param name="expr"/>
<xsl:choose>
<xsl:when test="$expr/selectable">
<xsl:value-of select="$expr/selectable/selector"/>
<xsl:text>: </xsl:text>
<xsl:call-template name="no-parenthesis">
<xsl:with-param name="expr" select="$expr/selectable/bgf:expression"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$expr/sequence">
<xsl:apply-templates select="$expr/sequence/bgf:expression[1]/*"/>
<xsl:for-each select="$expr/sequence/bgf:expression[position()&gt;1]">
<xsl:text> </xsl:text>
<xsl:apply-templates select="./*"/>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$expr"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="escape">
<xsl:param name="t"/>
<xsl:if test="$t != ''">
<xsl:variable name="c" select="substring($t, 1, 1)"/>
<xsl:if test="$c = '&lt;' or $c = '&gt;' or $c = '&quot;' or $c = '\' ">
<xsl:text>\</xsl:text>
</xsl:if>
<xsl:value-of select="$c"/>
<xsl:call-template name="escape">
<xsl:with-param name="t" select="substring($t, 2)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
12 changes: 12 additions & 0 deletions topics/grammars/abs/Makefile
@@ -0,0 +1,12 @@
all:
cp abs.prepared.parser abs.prepared.1
perl -pi -w -e 's/\/\//\n\/\//g;' abs.prepared.1
grep -v // abs.prepared.1 > abs.prepared.2
../../recovery/hunter/hunter.py abs.prepared.2 abs.edd raw.bgf
../../mutation/naming/enforce.py l_ C! raw.bgf rename.xbgf
xbgf rename.xbgf raw.bgf ext.1.bgf
xsltproc --stringparam grammarname ABS ../../export/rascal/bgf2rsc-unsafe.xslt ext.1.bgf > ABS.rsc
perl -pi -w -e 's/\./ //g;' ABS.rsc

clean:
rm -f *prepared* raw.bgf ext*.bgf rename.xbgf *.rsc
9 changes: 9 additions & 0 deletions topics/grammars/abs/README.txt
@@ -0,0 +1,9 @@
A VERY agile grammar recovery activity.
The sources were given to VVZ by Stijn de Gouw and contained the following:
// Grammar definition for the ABS language
// $Id: ABS.parser 15258 2012-05-04 14:30:36Z fkuehn $
(ABS.parser)
and:
//$Id: ABS.flex 13368 2012-01-16 10:47:25Z pzeller $
(ABS.flex)

34 changes: 34 additions & 0 deletions topics/grammars/abs/abs.edd
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<edd:config xmlns:edd="http://planet-sl.org/edd">
<!-- Crafted by Vadim Zaytsev, http://grammarware.net -->

<start-comment-symbol>{:</start-comment-symbol>
<end-comment-symbol>:}</end-comment-symbol>

<start-label-symbol>[</start-label-symbol>
<end-label-symbol>]</end-label-symbol>

<defining-symbol>=</defining-symbol>
<terminator-symbol>;</terminator-symbol>
<definition-separator-symbol>|</definition-separator-symbol>
<start-group-symbol>(</start-group-symbol>
<end-group-symbol>)</end-group-symbol>

<start-terminal-symbol>"</start-terminal-symbol>
<end-terminal-symbol>"</end-terminal-symbol>

<postfix-option-symbol>?</postfix-option-symbol>
<postfix-repetition-star-symbol>*</postfix-repetition-star-symbol>
<postfix-repetition-plus-symbol>+</postfix-repetition-plus-symbol>

<nonterminals-may-contain>.</nonterminals-may-contain>

<disregard-labels/>

<ignore>
<!-- Many pretty-printed LLL files contain lots and lots of newlines -->
<newline/>
<!-- Official format for comments -->
<!-- <lines-containing>#</lines-containing> -->
</ignore>
</edd:config>
119 changes: 119 additions & 0 deletions topics/grammars/abs/getkwd.py
@@ -0,0 +1,119 @@
kwds = '''
"module" { return sym(Terminals.MODULE); }
"import" { return sym(Terminals.IMPORT); }
"export" { return sym(Terminals.EXPORT); }
"from" { return sym(Terminals.FROM); }
"class" { return sym(Terminals.CLASS); }
"interface" { return sym(Terminals.INTERFACE); }
"extends" { return sym(Terminals.EXTENDS); }
"data" { return sym(Terminals.DATA); }
"def" { return sym(Terminals.DEF); }
"implements" { return sym(Terminals.IMPLEMENTS); }
"delta" { return sym(Terminals.DELTA); }
"adds" { return sym(Terminals.ADDS); }
"modifies" { return sym(Terminals.MODIFIES); }
"removes" { return sym(Terminals.REMOVES); }
"hasField" { return sym(Terminals.HASFIELD); }
"hasMethod" { return sym(Terminals.HASMETHOD); }
"hasInterface" { return sym(Terminals.HASINTERFACE); }
"productline" { return sym(Terminals.PRODUCTLINE); }
"features" { return sym(Terminals.OPTFEATURES); }
"after" { return sym(Terminals.AFTER); }
"when" { return sym(Terminals.WHEN); }
"product" { return sym(Terminals.PRODUCT); }
"while" { return sym(Terminals.WHILE); }
"return" { return sym(Terminals.RETURN); }
"skip" { return sym(Terminals.SKIP); }
"get" { return sym(Terminals.GET); }
"null" { return sym(Terminals.NULL); }
"await" { return sym(Terminals.AWAIT); }
"if" { return sym(Terminals.IF); }
"then" { return sym(Terminals.THEN); }
"else" { return sym(Terminals.ELSE); }
"suspend" { return sym(Terminals.SUSPEND); }
"duration" { return sym(Terminals.DURATION); }
"new" { return sym(Terminals.NEW); }
"this" { return sym(Terminals.THIS); }
"core" { return sym(Terminals.CORE); }
"original" { return sym(Terminals.ORIGINAL); }
".original" { return sym(Terminals.DOTORIGINAL); }
"case" { return sym(Terminals.CASE); }
"let" { return sym(Terminals.LET); }
"in" { return sym(Terminals.IN); }
"cog" { return sym(Terminals.COG); }
"type" { return sym(Terminals.TYPE); }
"assert" { return sym(Terminals.ASSERT); }
"builtin" { return sym(Terminals.BUILTIN); }
//
"root" { return sym(Terminals.ROOT); }
"extension" { return sym(Terminals.EXTENSION); }
"group" { return sym(Terminals.GROUP); }
"opt" { return sym(Terminals.OPT); }
"oneof" { return sym(Terminals.ONEOF); }
"allof" { return sym(Terminals.ALLOF); }
//"Int" { return sym(Terminals.INT); }
//"Bool" { return sym(Terminals.BOOL); }
//"in" { return sym(Terminals.IN); }
"ifin" { return sym(Terminals.IFIN); }
"ifout" { return sym(Terminals.IFOUT); }
"exclude" { return sym(Terminals.EXCLUDE); }
"require" { return sym(Terminals.REQUIRE); }
//"excludes" { return sym(Terminals.EXCLUDE); }
//"requires" { return sym(Terminals.REQUIRE); }
//"true" { return sym(Terminals.TRUE); }
//"tt" { return sym(Terminals.TRUE); }
//"false" { return sym(Terminals.FALSE); }
//"ff" { return sym(Terminals.FALSE); }
"(" { return sym(Terminals.LPAREN); }
")" { return sym(Terminals.RPAREN); }
"{" { return sym(Terminals.LBRACE); }
"}" { return sym(Terminals.RBRACE); }
"[" { return sym(Terminals.LBRACKET); }
"]" { return sym(Terminals.RBRACKET); }
"," { return sym(Terminals.COMMA); }
";" { return sym(Terminals.SEMICOLON); }
":" { return sym(Terminals.COLON); }
"?" { return sym(Terminals.QMARK); }
".." { return sym(Terminals.UNTIL); }
"." { return sym(Terminals.DOT); }
"!" { return sym(Terminals.BANG); }
"=" { return sym(Terminals.ASSIGN); }
"&" { return sym(Terminals.GUARDAND); }
"==" { return sym(Terminals.EQEQ); }
"!=" { return sym(Terminals.NOTEQ); }
"=>" { return sym(Terminals.RARROW); }
"->" { return sym(Terminals.IMPLIES); }
"<->" { return sym(Terminals.EQUIV); }
"+" { return sym(Terminals.PLUS); }
"-" { return sym(Terminals.MINUS); }
"*" { return sym(Terminals.MULT); }
"/" { return sym(Terminals.DIV); }
"%" { return sym(Terminals.MOD); }
"&&" { return sym(Terminals.ANDAND); }
"||" { return sym(Terminals.OROR); }
"|" { return sym(Terminals.BAR); }
"~" { return sym(Terminals.NEGATION); }
"<" { return sym(Terminals.LT); }
">" { return sym(Terminals.GT); }
"<=" { return sym(Terminals.LTEQ); }
">=" { return sym(Terminals.GTEQ); }
"_" { return sym(Terminals.USCORE); }
"'" { return sym(Terminals.PRIME); }
'''

defs = {}
for line in kwds.split('\n'):
line = line.strip()
if line.startswith('//'):
continue
elif line == '':
continue
else:
name = line.split('Terminals.')[1].split(')')[0]
defs[name] = line.split('"')[1]

for a in defs:
print 'lexical',a,'=', '"'+defs[a]+'"',';'
3 changes: 3 additions & 0 deletions topics/recovery/hunter/hunter.py
Expand Up @@ -1223,6 +1223,9 @@ def convertNonalphanumerics2Terminals(p):
print('STEP 5 warning:',repr(x),'is assumed to be an invalid nonterminal name, converted to a terminal symbol.')
q.append(config['start-terminal-symbol'] + x + config['end-terminal-symbol'])
continue
if not x:
# empty!
continue
string = x[0]
alpha = isAlphaNum(x[0])
if alpha and not (x[0].isalpha() or x[0] in nonterminals_start):
Expand Down

0 comments on commit a889685

Please sign in to comment.